put again eina tests in the source tree

SVN revision: 56193
This commit is contained in:
Vincent Torri 2011-01-16 17:55:41 +00:00
parent 6a5adabb1c
commit d3420a210d
61 changed files with 62611 additions and 2 deletions

View File

@ -41,18 +41,82 @@ eina.spec.in \
m4/ac_attribute.m4 \
m4/efl_benchmark.m4 \
m4/efl_compiler_flag.m4 \
m4/efl_coverage.m4 \
m4/efl_cpu.m4 \
m4/efl_doxygen.m4 \
m4/efl_fnmatch.m4 \
m4/efl_tests.m4 \
m4/efl_threads.m4 \
m4/eina_bench.m4 \
m4/eina_check.m4 \
m4/efl_path_max.m4
.PHONY: doc
.PHONY: doc coverage benchmark
# Documentation
doc:
@echo "entering doc/"
@cd doc && make doc
# Unit tests
if EFL_ENABLE_TESTS
check-local:
@./src/tests/eina_suite
else
check-local:
@echo "reconfigure with --enable-tests"
endif
# Coverage report
if EFL_ENABLE_COVERAGE
lcov-reset:
@rm -rf coverage
@find . -name "*.gcda" -exec rm {} \;
@lcov --directory . --zerocounters
lcov-report:
@mkdir coverage
@lcov --compat-libtool --directory $(top_srcdir)/src --capture --output-file coverage/coverage.info
@lcov -l coverage/coverage.info |grep "\\.h" |cut -d " " -f 2 > coverage/remove
@lcov -r coverage/coverage.info `cat coverage/remove` > coverage/coverage.cleaned.info
@rm coverage/remove
@mv coverage/coverage.cleaned.info coverage/coverage.info
@genhtml -t "$(PACKAGE_STRING)" -o coverage coverage/coverage.info
coverage:
@make lcov-reset
@make check
@make lcov-report
else
lcov-reset:
@echo "reconfigure with --enable-coverage"
lcov-report:
@echo "reconfigure with --enable-coverage"
coverage:
@echo "reconfigure with --enable-tests --enable-coverage"
endif
if EFL_ENABLE_BENCHMARK
benchmark:
@cd src && make benchmark
@mkdir result || true
@cd result && ../src/tests/eina_bench `date +%F_%s`
else
benchmark:
@echo "reconfigure with --enable-benchmark"
endif
clean-local:
@rm -rf coverage benchmark

View File

@ -569,6 +569,20 @@ EINA_CHECK_MODULE([one-big], [${enable_one_big}], [one big])
### Make the debug preprocessor configurable
### Unit tests, coverage and benchmarking
EFL_CHECK_TESTS([enable_tests="yes"], [enable_tests="no"])
EFL_CHECK_COVERAGE([${enable_tests}], [enable_coverage="yes"], [enable_coverage="no"])
EINA_CFLAGS="${EINA_CFLAGS} ${EFL_COVERAGE_CFLAGS}"
EINA_LIBS="${EINA_LIBS} ${EFL_COVERAGE_LIBS}"
if test "x$enable_coverage" = "xyes" ; then
EINA_CFLAGS="${EINA_CFLAGS} ${EFL_DEBUG_CFLAGS}"
fi
EFL_CHECK_BENCHMARK([enable_benchmark="yes"], [enable_benchmark="no"])
EINA_BENCH_MODULE([glib], [${enable_benchmark}], [glib-2.0], [enable_benchmark_glib="yes"], [enable_benchmark_glib="no"])
AC_SUBST(requirement_eina)
### Create the .pc.in file according to the major version
@ -605,6 +619,7 @@ src/modules/mp/pass_through/Makefile
src/modules/mp/fixed_bitmap/Makefile
src/modules/mp/buddy/Makefile
src/modules/mp/one_big/Makefile
src/tests/Makefile
])
AC_OUTPUT
@ -638,6 +653,13 @@ echo " Iconv support........: ${have_iconv}"
echo " File dirfd...........: ${have_dirfd}"
echo
echo " Documentation........: ${build_doc}"
echo " Tests................: ${enable_tests}"
echo " Coverage.............: ${enable_coverage}"
echo " Benchmark............: ${enable_benchmark}"
if test "x${enable_benchmark}" = "xyes" ; then
echo " Glib...............: ${enable_benchmark_glib}"
echo " E17 real data......: ${enable_benchmark_e17}"
fi
echo
echo " CPU Specific Extensions:"
echo " MMX................: ${have_mmx}"

View File

@ -1,3 +1,17 @@
SUBDIRS = lib include modules
SUBDIRS = lib include modules tests
MAINTAINERCLEANFILES = Makefile.in
.PHONY: benchmark
if EFL_ENABLE_BENCHMARK
benchmark: all
cd tests && make eina_bench
else
benchmark:
@echo "reconfigure with --enable-benchmark"
endif

View File

@ -0,0 +1,557 @@
#ifndef _ECORE_DATA_H
# define _ECORE_DATA_H
#include <stdio.h>
/* we need this for size_t */
#include <stddef.h>
#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
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#ifdef FREE
# undef FREE
#endif
#define FREE(ptr) free(ptr); ptr = NULL;
#ifdef IF_FREE
# undef IF_FREE
#endif
#define IF_FREE(ptr) if (ptr) {free(ptr); } ptr = NULL;
/* convenience macros for checking pointer parameters for non-NULL */
#undef CHECK_PARAM_POINTER_RETURN
#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
if (!(param)) \
{ \
printf("***** Developer Warning ***** :\n" \
"\tThis program is calling:\n\n" \
"\t%s();\n\n" \
"\tWith the parameter:\n\n" \
"\t%s\n\n" \
"\tbeing NULL. Please fix your program.", __FUNCTION__, sparam); \
if (getenv("ECORE_ERROR_ABORT")) { abort(); } \
return ret; \
}
#undef CHECK_PARAM_POINTER
#define CHECK_PARAM_POINTER(sparam, param) \
if (!(param)) \
{ \
printf("***** Developer Warning ***** :\n" \
"\tThis program is calling:\n\n" \
"\t%s();\n\n" \
"\tWith the parameter:\n\n" \
"\t%s\n\n" \
"\tbeing NULL. Please fix your program.", __FUNCTION__, sparam); \
if (getenv("ECORE_ERROR_ABORT")) { abort(); } \
return; \
}
# ifdef __sgi
# define __FUNCTION__ "unknown"
# ifndef __cplusplus
# define inline
# endif
# endif
# 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 struct _ecore_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);
EAPI int ecore_str_compare(const void *key1, const void *key2);
EAPI unsigned int ecore_direct_hash(const void *key);
EAPI unsigned int ecore_str_hash(const void *key);
/* Creating and initializing new list structures */
EAPI Ecore_List * ecore_list_new(void);
EAPI int ecore_list_init(Ecore_List *list);
/* Adding items to the list */
EAPI int ecore_list_append(Ecore_List *list, void *_data);
EAPI int ecore_list_prepend(Ecore_List *list, void *_data);
EAPI int ecore_list_insert(Ecore_List *list, void *_data);
EAPI int ecore_list_append_list(Ecore_List *list,
Ecore_List *append);
EAPI int ecore_list_prepend_list(Ecore_List *list,
Ecore_List *prepend);
/* Removing items from the list */
EAPI int ecore_list_remove_destroy(Ecore_List *list);
EAPI void * ecore_list_remove(Ecore_List *list);
EAPI void * ecore_list_first_remove(Ecore_List *list);
EAPI void * ecore_list_last_remove(Ecore_List *list);
/* Retrieve the current position in the list */
EAPI void * ecore_list_current(Ecore_List *list);
EAPI void * ecore_list_first(Ecore_List *list);
EAPI void * ecore_list_last(Ecore_List *list);
EAPI int ecore_list_index(Ecore_List *list);
EAPI int ecore_list_count(Ecore_List *list);
/* Traversing the list */
EAPI int ecore_list_for_each(Ecore_List *list,
Ecore_For_Each function,
void *user_data);
EAPI void * ecore_list_first_goto(Ecore_List *list);
EAPI void * ecore_list_last_goto(Ecore_List *list);
EAPI void * ecore_list_index_goto(Ecore_List *list, int index);
EAPI void * ecore_list_goto(Ecore_List *list, const void *_data);
/* Traversing the list and returning data */
EAPI void * ecore_list_next(Ecore_List *list);
EAPI void * ecore_list_find(Ecore_List *list,
Ecore_Compare_Cb function,
const void *user_data);
/* Sorting the list */
EAPI int ecore_list_sort(Ecore_List *list,
Ecore_Compare_Cb compare,
char order);
EAPI int ecore_list_mergesort(Ecore_List *list,
Ecore_Compare_Cb compare,
char order);
EAPI int ecore_list_heapsort(Ecore_List *list,
Ecore_Compare_Cb compare,
char order);
EAPI void ecore_list_merge(Ecore_List *list, Ecore_List *l2,
Ecore_Compare_Cb, char order);
/* Check to see if there is any data in the list */
EAPI int ecore_list_empty_is(Ecore_List *list);
/* Remove every node in the list without freeing the list itself */
EAPI int ecore_list_clear(Ecore_List *list);
/* Free the list and it's contents */
EAPI void ecore_list_destroy(Ecore_List *list);
/* Creating and initializing list nodes */
EAPI Ecore_List_Node *ecore_list_node_new(void);
EAPI int ecore_list_node_init(Ecore_List_Node *newNode);
/* Destroying nodes */
EAPI int ecore_list_node_destroy(Ecore_List_Node *_e_node,
Ecore_Free_Cb free_func);
EAPI int ecore_list_free_cb_set(Ecore_List *list,
Ecore_Free_Cb free_func);
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);
EAPI int ecore_dlist_init(Ecore_DList *list);
EAPI void ecore_dlist_destroy(Ecore_DList *list);
/* Adding items to the list */
EAPI int ecore_dlist_append(Ecore_DList *_e_dlist, void *_data);
EAPI int ecore_dlist_prepend(Ecore_DList *_e_dlist, void *_data);
EAPI int ecore_dlist_insert(Ecore_DList *_e_dlist, void *_data);
EAPI int ecore_dlist_append_list(Ecore_DList *_e_dlist,
Ecore_DList *append);
EAPI int ecore_dlist_prepend_list(Ecore_DList *_e_dlist,
Ecore_DList *prepend);
/* 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);
EAPI int ecore_dlist_index(Ecore_DList *list);
# define ecore_dlist_count(list) ecore_list_count(list)
/* Removing items from the list */
EAPI void * ecore_dlist_remove(Ecore_DList *_e_dlist);
EAPI void * ecore_dlist_first_remove(Ecore_DList *_e_dlist);
EAPI int ecore_dlist_remove_destroy(Ecore_DList *list);
EAPI void * ecore_dlist_last_remove(Ecore_DList *_e_dlist);
/* 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);
EAPI void * ecore_dlist_last_goto(Ecore_DList *_e_dlist);
EAPI void * ecore_dlist_index_goto(Ecore_DList *_e_dlist, int index);
EAPI void * ecore_dlist_goto(Ecore_DList *_e_dlist, void *_data);
/* Traversing the list and returning data */
EAPI void * ecore_dlist_next(Ecore_DList *list);
EAPI void * ecore_dlist_previous(Ecore_DList *list);
/* Sorting the list */
EAPI int ecore_dlist_sort(Ecore_DList *list,
Ecore_Compare_Cb compare,
char order);
EAPI int ecore_dlist_mergesort(Ecore_DList *list,
Ecore_Compare_Cb compare,
char order);
# 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);
/* Check to see if there is any data in the list */
EAPI int ecore_dlist_empty_is(Ecore_DList *_e_dlist);
/* Remove every node in the list without free'ing it */
EAPI int ecore_dlist_clear(Ecore_DList *_e_dlist);
/* Creating and initializing list nodes */
EAPI int ecore_dlist_node_init(Ecore_DList_Node *node);
EAPI Ecore_DList_Node *ecore_dlist_node_new(void);
/* Destroying nodes */
EAPI int ecore_dlist_node_destroy(Ecore_DList_Node *node,
Ecore_Free_Cb free_func);
EAPI int ecore_dlist_free_cb_set(Ecore_DList *dlist,
Ecore_Free_Cb free_func);
/*
* 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);
EAPI int ecore_hash_init(Ecore_Hash *hash,
Ecore_Hash_Cb hash_func,
Ecore_Compare_Cb compare);
/* 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);
EAPI int ecore_hash_free_value_cb_set(Ecore_Hash *hash,
Ecore_Free_Cb function);
EAPI void ecore_hash_destroy(Ecore_Hash *hash);
EAPI int ecore_hash_count(Ecore_Hash *hash);
EAPI int ecore_hash_for_each_node(Ecore_Hash *hash,
Ecore_For_Each for_each_func,
void *user_data);
EAPI Ecore_List *ecore_hash_keys(Ecore_Hash *hash);
/* Retrieve and store data into the hash */
EAPI void * ecore_hash_get(Ecore_Hash *hash, const void *key);
EAPI int ecore_hash_set(Ecore_Hash *hash, void *key, void *value);
EAPI int ecore_hash_hash_set(Ecore_Hash *hash, Ecore_Hash *set);
EAPI void * ecore_hash_remove(Ecore_Hash *hash, const void *key);
EAPI void * ecore_hash_find(Ecore_Hash *hash,
Ecore_Compare_Cb compare,
const void *value);
EAPI void ecore_hash_dump_graph(Ecore_Hash *hash);
EAPI void ecore_hash_dump_stats(Ecore_Hash *hash);
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);
EAPI void ecore_sheap_destroy(Ecore_Sheap *heap);
EAPI int ecore_sheap_init(Ecore_Sheap *heap,
Ecore_Compare_Cb compare,
int size);
EAPI int ecore_sheap_free_cb_set(Ecore_Sheap *heap,
Ecore_Free_Cb free_func);
EAPI int ecore_sheap_insert(Ecore_Sheap *heap, void *data);
EAPI void * ecore_sheap_extract(Ecore_Sheap *heap);
EAPI void * ecore_sheap_extreme(Ecore_Sheap *heap);
EAPI int ecore_sheap_change(Ecore_Sheap *heap,
void *item,
void *newval);
EAPI int ecore_sheap_compare_set(Ecore_Sheap *heap,
Ecore_Compare_Cb compare);
EAPI void ecore_sheap_order_set(Ecore_Sheap *heap, char order);
EAPI void ecore_sheap_sort(Ecore_Sheap *heap);
EAPI void * ecore_sheap_item(Ecore_Sheap *heap, int i);
typedef struct _ecore_string Ecore_String;
struct _ecore_string
{
char *string;
int references;
};
EAPI int ecore_string_init();
EAPI void ecore_string_shutdown();
EAPI const char *ecore_string_instance(const char *string);
EAPI void ecore_string_release(const char *string);
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);
/* Initialize a new tree */
EAPI int ecore_tree_init(Ecore_Tree *tree,
Ecore_Compare_Cb compare_func);
/* Free the tree */
EAPI int ecore_tree_destroy(Ecore_Tree *tree);
/* Check to see if the tree has any nodes in it */
EAPI int ecore_tree_empty_is(Ecore_Tree *tree);
/* Retrieve the value associated with key */
EAPI void * ecore_tree_get(Ecore_Tree *tree, const void *key);
EAPI Ecore_Tree_Node *ecore_tree_get_node(Ecore_Tree *tree, const void *key);
/* 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);
/* 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);
/* Set the value associated with key to value */
EAPI int ecore_tree_set(Ecore_Tree *tree, void *key, void *value);
/* Remove the key from the tree */
EAPI int ecore_tree_remove(Ecore_Tree *tree, const void *key);
/* Add a node to the tree */
EAPI int ecore_tree_node_add(Ecore_Tree *tree,
Ecore_Tree_Node *node);
/* Remove a node from the tree */
EAPI int ecore_tree_node_remove(Ecore_Tree *tree,
Ecore_Tree_Node *node);
/* 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);
/* 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);
/* Some basic node functions */
/* Initialize a node */
EAPI int ecore_tree_node_init(Ecore_Tree_Node *new_node);
/* Allocate and initialize a new node */
EAPI Ecore_Tree_Node *ecore_tree_node_new(void);
/* Free the desired node */
EAPI int ecore_tree_node_destroy(Ecore_Tree_Node *node,
Ecore_Free_Cb free_value,
Ecore_Free_Cb free_key);
/* Set the node's key to key */
EAPI int ecore_tree_node_key_set(Ecore_Tree_Node *node, void *key);
/* Retrieve the key in node */
EAPI void * ecore_tree_node_key_get(Ecore_Tree_Node *node);
/* Set the node's value to value */
EAPI int ecore_tree_node_value_set(Ecore_Tree_Node *node,
void *value);
/* Retrieve the value in node */
EAPI void * ecore_tree_node_value_get(Ecore_Tree_Node *node);
/* 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);
/* 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);
EAPI Ecore_Strbuf * ecore_strbuf_new(void);
EAPI void ecore_strbuf_free(Ecore_Strbuf *buf);
EAPI void ecore_strbuf_append(Ecore_Strbuf *buf, const char *str);
EAPI void ecore_strbuf_append_char(Ecore_Strbuf *buf, char c);
EAPI void ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str,
size_t pos);
# define ecore_strbuf_prepend(buf, str) ecore_strbuf_insert(buf, str, 0)
EAPI const char * ecore_strbuf_string_get(Ecore_Strbuf *buf);
EAPI size_t ecore_strbuf_length_get(Ecore_Strbuf *buf);
EAPI int ecore_strbuf_replace(Ecore_Strbuf *buf, const char *str,
const char *with, unsigned int n);
# 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);
extern int ecore_str_compare(const void *key1, const void *key2);
extern int ecore_direct_compare(const void *key1, const void *key2);
extern unsigned int ecore_str_hash(const void *key);
#ifdef __cplusplus
}
#endif
#endif /* _ECORE_DATA_H */

View File

@ -0,0 +1,195 @@
#ifndef _EVAS_DATA_H
#define _EVAS_DATA_H
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EFL_EVAS_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EFL_EVAS_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
/**
* @file
* @brief These routines are used for Evas data types.
*/
typedef unsigned char Evas_Bool;
typedef struct _Evas_Array_Hash Evas_Array_Hash;
typedef struct _Evas_Hash Evas_Hash; /**< A Hash table handle */
typedef struct _Evas_List Evas_List; /**< A generic linked list node handle */
typedef struct _Evas_Object_List Evas_Object_List;
struct _Evas_Hash
{
int population;
Evas_Object_List *buckets[256];
};
struct _Evas_List /** A linked list node */
{
void *data; /**< Pointer to list element payload */
Evas_List *next; /**< Next member in the list */
Evas_List *prev; /**< Previous member in the list */
struct _Evas_List_Accounting *accounting; /**< Private list accounting info - don't touch */
};
struct _Evas_Object_List
{
Evas_Object_List *next, *prev;
Evas_Object_List *last;
};
#ifdef __cplusplus
extern "C" {
#endif
/*
* Evas Array Hash functions
*/
EAPI Evas_Array_Hash *evas_array_hash_new (void);
EAPI void evas_array_hash_free (Evas_Array_Hash *hash);
EAPI void evas_array_hash_add (Evas_Array_Hash *hash,
int key,
int data);
EAPI int evas_array_hash_search (Evas_Array_Hash *hash,
int key);
/*
* Evas Hash functions
*/
/* FIXME: add:
* api to add find, del members by data, size not just string and also
* provide hash generation functions settable by the app
*
* do we really need this? hmmm - let me think... there may be a better way
*/
EAPI Evas_Hash *evas_hash_add (Evas_Hash *hash,
const char *key,
const void *data);
EAPI Evas_Hash *evas_hash_direct_add (Evas_Hash *hash,
const char *key,
const void *data);
EAPI Evas_Hash *evas_hash_del (Evas_Hash *hash,
const char *key,
const void *data);
EAPI void * evas_hash_find (const Evas_Hash *hash,
const char *key);
EAPI void * evas_hash_modify (Evas_Hash *hash,
const char *key,
const void *data);
EAPI int evas_hash_size (const Evas_Hash *hash);
EAPI void evas_hash_free (Evas_Hash *hash);
EAPI void evas_hash_foreach (const Evas_Hash *hash,
Evas_Bool (*func)(
const Evas_Hash *hash,
const char *
key,
void *data,
void *fdata),
const void *fdata);
EAPI int evas_hash_alloc_error (void);
/*
* Evas List functions
*/
EAPI Evas_List *evas_list_append (Evas_List *list,
const void *data);
EAPI Evas_List *evas_list_prepend (Evas_List *list,
const void *data);
EAPI Evas_List *evas_list_append_relative (Evas_List *list,
const void *data,
const void *relative);
EAPI Evas_List *evas_list_append_relative_list (Evas_List *list,
const void *data,
Evas_List *relative);
EAPI Evas_List *evas_list_prepend_relative (Evas_List *list,
const void *data,
const void *relative);
EAPI Evas_List *evas_list_prepend_relative_list (Evas_List *list,
const void *data,
Evas_List *relative);
EAPI Evas_List *evas_list_remove (Evas_List *list,
const void *data);
EAPI Evas_List *evas_list_remove_list (Evas_List *list,
Evas_List *remove_list);
EAPI Evas_List *evas_list_promote_list (Evas_List *list,
Evas_List *move_list);
EAPI void * evas_list_find (const Evas_List *list,
const void *data);
EAPI Evas_List *evas_list_find_list (const Evas_List *list,
const void *data);
EAPI Evas_List *evas_list_free (Evas_List *list);
EAPI Evas_List *evas_list_last (const Evas_List *list);
EAPI Evas_List *evas_list_next (const Evas_List *list);
EAPI Evas_List *evas_list_prev (const Evas_List *list);
EAPI void * evas_list_data (const Evas_List *list);
EAPI int evas_list_count (const Evas_List *list);
EAPI void * evas_list_nth (const Evas_List *list, int n);
EAPI Evas_List *evas_list_nth_list (const Evas_List *list, int n);
EAPI Evas_List *evas_list_reverse (Evas_List *list);
EAPI Evas_List *evas_list_sort (Evas_List *list,
int size,
int (*func)(void *,void *));
EAPI int evas_list_alloc_error (void);
/*
* Evas Object List functions
*/
EAPI void * evas_object_list_append (void *in_list,
void *in_item);
EAPI void * evas_object_list_prepend (void *in_list,
void *in_item);
EAPI void * evas_object_list_append_relative (void *in_list,
void *in_item,
void *in_relative);
EAPI void * evas_object_list_prepend_relative (void *in_list,
void *in_item,
void *in_relative);
EAPI void * evas_object_list_remove (void *in_list,
void *in_item);
EAPI void * evas_object_list_find (void *in_list,
void *in_item);
/*
* Evas Stringshare functions
*/
EAPI void evas_stringshare_init (void); /* not implemented */
EAPI void evas_stringshare_shutdown (void); /* not implemented */
EAPI const char *evas_stringshare_add (const char *str);
EAPI void evas_stringshare_del (const char *str);
#ifdef __cplusplus
}
#endif
#endif /* _EVAS_DATA_H */

View File

@ -0,0 +1,120 @@
MAINTAINERCLEANFILES = Makefile.in
benchdir = $(bindir)
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/include \
-I$(top_builddir)/src/include \
-I$(top_builddir)/src/lib \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)\" \
@CHECK_CFLAGS@ \
@GLIB_CFLAGS@
if EINA_HAVE_GLIB
AM_CPPFLAGS += -DEINA_BENCH_HAVE_GLIB
endif
if EINA_ENABLE_BENCHMARK_E17
AM_CPPFLAGS += -DEINA_ENABLE_BENCH_E17
endif
if EFL_ENABLE_TESTS
check_PROGRAMS = eina_suite
eina_suite_SOURCES = \
eina_suite.c \
eina_test_fp.c \
eina_test_stringshare.c \
eina_test_ustringshare.c\
eina_test_ustr.c \
eina_test_binshare.c \
eina_test_array.c \
eina_test_error.c \
eina_test_sched.c \
eina_test_log.c \
eina_test_magic.c \
eina_test_inlist.c \
eina_test_main.c \
eina_test_counter.c \
eina_test_lalloc.c \
eina_test_hash.c \
eina_test_iterator.c \
eina_test_accessor.c \
eina_test_module.c \
eina_test_convert.c \
eina_test_rbtree.c \
eina_test_file.c \
eina_test_benchmark.c \
eina_test_mempool.c \
eina_test_rectangle.c \
eina_test_list.c \
eina_test_matrixsparse.c \
eina_test_tiler.c \
eina_test_strbuf.c \
eina_test_str.c \
eina_test_quadtree.c
eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la -lm
module_dummydir = $(libdir)/eina/test
module_dummy_LTLIBRARIES = module_dummy.la
module_dummy_la_SOURCES = \
eina_test_module_dummy.c
module_dummy_la_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/include \
-I$(top_builddir)/src/include \
-I$(top_builddir)/src/lib \
@EFL_EINA_BUILD@
module_dummy_la_LIBADD = $(top_builddir)/src/lib/libeina.la @EINA_LIBS@
module_dummy_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
module_dummy_la_LIBTOOLFLAGS = --tag=disable-static
endif
if EFL_ENABLE_BENCHMARK
bench_PROGRAMS = eina_bench
eina_bench_SOURCES = \
eina_bench.c \
eina_bench_sort.c \
eina_bench_hash.c \
eina_bench_stringshare.c \
eina_bench_convert.c \
eina_bench_mempool.c \
eina_bench_stringshare_e17.c \
eina_bench_array.c \
eina_bench_rectangle_pool.c \
ecore_list.c \
ecore_strings.c \
ecore_hash.c \
ecore_sheap.c \
evas_hash.c \
evas_list.c \
evas_mempool.c \
evas_object_list.c \
evas_stringshare.c \
eina_bench_quad.c
eina_bench_LDADD = @GLIB_LIBS@ $(top_builddir)/src/lib/libeina.la
endif
EXTRA_DIST = eina_bench.h \
eina_suite.h \
Ecore_Data.h \
Evas_Data.h \
evas_mempool.h \
strlog

View File

@ -0,0 +1,949 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Ecore_Data.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 : 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) : FALSE)
static 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
};
/* 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));
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 TRUE on success, @c 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, 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 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 TRUE on success, @c 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, FALSE);
hash->free_key = function;
return 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 TRUE on success, @c 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, FALSE);
hash->free_value = function;
return 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 TRUE if successful, @c FALSE if not.
* @ingroup Ecore_Data_Hash_ADT_Data_Group
*/
EAPI int
ecore_hash_set(Ecore_Hash *hash, void *key, void *value)
{
int ret = FALSE;
Ecore_Hash_Node *node;
CHECK_PARAM_POINTER_RETURN("hash", hash, 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 = 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 TRUE if successful, @c 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, FALSE);
CHECK_PARAM_POINTER_RETURN("set", set, 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 TRUE;
}
/**
* Frees the hash table and the data contained inside it.
* @param hash The hash table to destroy.
* @return @c TRUE on success, @c 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 TRUE on success, 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, FALSE);
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, 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 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++;
printf("%d\t%u", i, n);
}
else
printf("%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;
printf("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, FALSE);
for (node = list; node; node = list)
{
list = list->next;
_ecore_hash_node_destroy(node, keyd, valued);
}
return 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 FALSE on error, 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, FALSE);
CHECK_PARAM_POINTER_RETURN("node", node, 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 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 TRUE on success, FALSE on error
*/
static int
_ecore_hash_increase(Ecore_Hash *hash)
{
void *old;
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
/* Max size reached so return FALSE */
if ((ecore_prime_table[hash->size] == PRIME_MAX) ||
(hash->size == PRIME_TABLE_MAX))
return 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 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 TRUE;
}
/*
* Free the old buckets regardless of success.
*/
FREE(old);
return 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 TRUE on success, FALSE on error
*/
static int
_ecore_hash_decrease(Ecore_Hash *hash)
{
Ecore_Hash_Node **old;
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
if (ecore_prime_table[hash->size] == PRIME_MIN)
return 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 FALSE;
}
hash->nodes = 0;
if (_ecore_hash_rehash(hash, old, hash->size + 1))
{
FREE(old);
return TRUE;
}
return 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 TRUE on success, 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, FALSE);
CHECK_PARAM_POINTER_RETURN("old_table", old_table, 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 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 TRUE on success, FALSE on error
*/
static int
_ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value)
{
CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
node->key = key;
node->value = value;
return 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 TRUE on success, 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, FALSE);
if (keyd)
keyd(node->key);
if (valued)
valued(node->value);
FREE(node);
return TRUE;
}
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);
}
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;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,467 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <string.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 TRUE on success, FALSE on failure
*/
EAPI int
ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size)
{
CHECK_PARAM_POINTER_RETURN("heap", heap, 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 FALSE;
memset(heap->data, 0, heap->space * sizeof(void *));
return 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 TRUE on successful set, @c FALSE otherwise.
*/
EAPI int
ecore_sheap_free_cb_set(Ecore_Sheap *heap, Ecore_Free_Cb free_func)
{
CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE);
heap->free_func = free_func;
return 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 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, 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 FALSE;
heap->sorted = 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 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 = 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 TRUE on success, 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, FALSE);
for (i = 0; i < heap->size && heap->compare(heap->data[i], item); i++) ;
if (i < heap->size)
heap->data[i] = newval;
else
return FALSE;
/*
* FIXME: This is not the correct procedure when a change occurs.
*/
_ecore_sheap_heapify(heap, 1);
return 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 TRUE on success, 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, FALSE);
if (!compare)
heap->compare = ecore_direct_compare;
else
heap->compare = compare;
_ecore_sheap_update_data(heap);
return 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 = 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);
}
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;
}

View File

@ -0,0 +1,160 @@
#include <stdlib.h>
#include <string.h>
#include "Ecore_Data.h"
static void ecore_string_free_cb(void *data);
static Ecore_Hash *ecore_strings = NULL;
static int ecore_string_init_count = 0;
/**
* @defgroup Ecore_String_Group String Instance Functions
*
* These functions allow you to store one copy of a string, and use it
* throughout your program.
*
* This is a method to reduce the number of duplicated strings kept in
* memory. It's pretty common for the same strings to be dynamically
* allocated repeatedly between applications and libraries, especially in
* circumstances where you could have multiple copies of a structure that
* allocates the string. So rather than duplicating and freeing these
* strings, you request a read-only pointer to an existing string and
* only incur the overhead of a hash lookup.
*
* It sounds like micro-optimizing, but profiling has shown this can have
* a significant impact as you scale the number of copies up. It improves
* string creation/destruction speed, reduces memory use and decreases
* memory fragmentation, so a win all-around.
*/
/**
* Initialize the ecore string internal structure.
* @return Zero on failure, non-zero on successful initialization.
*/
EAPI int
ecore_string_init()
{
/*
* No strings have been loaded at this point, so create the hash
* table for storing string info for later.
*/
if (!ecore_string_init_count)
{
ecore_strings = ecore_hash_new(ecore_str_hash, ecore_str_compare);
if (!ecore_strings)
return 0;
ecore_hash_free_value_cb_set(ecore_strings, ecore_string_free_cb);
}
ecore_string_init_count++;
return 1;
}
/**
* Retrieves an instance of a string for use in an ecore program.
* @param string The string to retrieve an instance of.
* @return A pointer to an instance of the string on success.
* @c NULL on failure.
* @ingroup Ecore_String_Group
*/
EAPI const char *
ecore_string_instance(const char *string)
{
Ecore_String *str;
CHECK_PARAM_POINTER_RETURN("string", string, NULL);
/*
* Check for a previous instance of the string, if not found, create
* it.
*/
str = ecore_hash_get(ecore_strings, string);
if (!str)
{
int length;
/*
* Allocate and initialize a new string reference.
*/
length = strlen(string) + 1;
str =
(Ecore_String *)malloc(sizeof(Ecore_String) + length * sizeof(char));
str->string = (char *)(str + 1);
str->references = 0;
memcpy(str->string, string, length);
ecore_hash_set(ecore_strings, str->string, str);
}
str->references++;
return str->string;
}
/**
* Notes that the given string has lost an instance.
*
* It will free the string if no other instances are left.
*
* @param string The given string.
* @ingroup Ecore_String_Group
*/
EAPI void
ecore_string_release(const char *string)
{
Ecore_String *str;
CHECK_PARAM_POINTER("string", string);
str = ecore_hash_get(ecore_strings, (char *)string);
if (!str)
return;
str->references--;
if (str->references < 1)
{
ecore_hash_remove(ecore_strings, (char *)string);
FREE(str);
}
}
EAPI void
ecore_string_hash_dump_graph(void)
{
ecore_hash_dump_graph(ecore_strings);
}
EAPI void
ecore_string_hash_dump_stats(void)
{
ecore_hash_dump_stats(ecore_strings);
}
/**
* Shutdown the ecore string internal structures
*/
EAPI void
ecore_string_shutdown()
{
--ecore_string_init_count;
if (!ecore_string_init_count)
{
ecore_hash_destroy(ecore_strings);
ecore_strings = NULL;
}
}
static void
ecore_string_free_cb(void *data)
{
Ecore_String *str;
str = data;
FREE(str);
}

View File

@ -0,0 +1,105 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "eina_bench.h"
#include "Eina.h"
typedef struct _Eina_Benchmark_Case Eina_Benchmark_Case;
struct _Eina_Benchmark_Case
{
const char *bench_case;
void (*build)(Eina_Benchmark *bench);
};
static const Eina_Benchmark_Case etc[] = {
/* { "Hash", eina_bench_hash }, */
/* { "Array vs List vs Inlist", eina_bench_array }, */
/* { "Stringshare", eina_bench_stringshare }, */
/* { "Convert", eina_bench_convert }, */
/* { "Sort", eina_bench_sort }, */
/* { "Mempool", eina_bench_mempool }, */
/* { "Rectangle_Pool", eina_bench_rectangle_pool }, */
{ "Render Loop", eina_bench_quadtree },
{ NULL, NULL }
};
/* FIXME this is a copy from eina_test_mempool
* we should remove the duplication
*/
static Eina_Array *_modules;
static void _mempool_init(void)
{
eina_init();
/* force modules to be loaded in case they are not installed */
_modules = eina_module_list_get(NULL,
PACKAGE_BUILD_DIR "/src/modules",
EINA_TRUE,
NULL,
NULL);
eina_module_list_load(_modules);
}
static void _mempool_shutdown(void)
{
eina_module_list_free(_modules);
/* TODO delete the list */
eina_shutdown();
}
int
main(int argc, char **argv)
{
Eina_Benchmark *test;
Eina_Array *ea;
unsigned int i;
if (argc != 2)
return -1;
_mempool_init();
eina_init();
for (i = 0; etc[i].bench_case; ++i)
{
test = eina_benchmark_new(etc[i].bench_case, argv[1]);
if (!test)
continue;
etc[i].build(test);
ea = eina_benchmark_run(test);
eina_benchmark_free(test);
}
eina_bench_e17();
eina_shutdown();
_mempool_shutdown();
return 0;
}

View File

@ -0,0 +1,36 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EINA_BENCH_H_
#define EINA_BENCH_H_
#include "eina_benchmark.h"
void eina_bench_hash(Eina_Benchmark *bench);
void eina_bench_array(Eina_Benchmark *bench);
void eina_bench_stringshare(Eina_Benchmark *bench);
void eina_bench_convert(Eina_Benchmark *bench);
void eina_bench_sort(Eina_Benchmark *bench);
void eina_bench_mempool(Eina_Benchmark *bench);
void eina_bench_rectangle_pool(Eina_Benchmark *bench);
void eina_bench_quadtree(Eina_Benchmark *bench);
/* Specific benchmark. */
void eina_bench_e17(void);
#endif

View File

@ -0,0 +1,699 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#ifdef EINA_BENCH_HAVE_GLIB
# include <glib.h>
#endif
#include "Evas_Data.h"
#include "Ecore_Data.h"
#include "eina_bench.h"
#include "eina_array.h"
#include "eina_list.h"
#include "eina_inlist.h"
#include "eina_main.h"
typedef struct _Eina_Bench_Object Eina_Bench_Object;
struct _Eina_Bench_Object
{
EINA_INLIST;
void *somewhere;
int data;
Eina_Bool keep;
};
static Eina_Bool keep(void *data, __UNUSED__ void *gdata)
{
Eina_Bench_Object *bo = data;
if (bo->keep == EINA_TRUE)
return EINA_TRUE;
free(bo);
return EINA_FALSE;
}
static void
eina_bench_array_4evas_render_inline(int request)
{
Eina_Array *array;
Eina_Bench_Object *ebo;
Eina_Array_Iterator it;
unsigned int i;
unsigned int j;
srand(time(NULL));
eina_init();
array = eina_array_new(64);
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < (unsigned int)request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
eina_array_push(array, ebo);
}
if (i == 500)
{
EINA_ARRAY_ITER_NEXT(array, j, ebo, it)
free(ebo);
eina_array_clean(array);
}
else if (i % 30 == 0)
eina_array_remove(array, keep, NULL);
EINA_ARRAY_ITER_NEXT(array, j, ebo, it)
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
}
EINA_ARRAY_ITER_NEXT(array, j, ebo, it)
free(ebo);
eina_array_free(array);
eina_shutdown();
}
static Eina_Bool
eina_iterator_ebo_free(__UNUSED__ const Eina_Array *array,
Eina_Bench_Object *ebo, __UNUSED__ void *fdata)
{
free(ebo);
return EINA_TRUE;
}
static Eina_Bool
eina_iterator_ebo_rand(__UNUSED__ const void *container,
Eina_Bench_Object *ebo, __UNUSED__ void *fdata)
{
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
return EINA_TRUE;
}
static void
eina_bench_array_4evas_render_iterator(int request)
{
Eina_Array *array;
Eina_Bench_Object *ebo;
Eina_Iterator *it;
unsigned int i;
unsigned int j;
srand(time(NULL));
eina_init();
array = eina_array_new(64);
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < (unsigned int)request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
eina_array_push(array, ebo);
}
if (i == 500)
{
it = eina_array_iterator_new(array);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_ebo_free), NULL);
eina_iterator_free(it);
eina_array_clean(array);
}
else if (i % 30 == 0)
eina_array_remove(array, keep, NULL);
it = eina_array_iterator_new(array);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_ebo_rand), NULL);
eina_iterator_free(it);
}
it = eina_array_iterator_new(array);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_ebo_free), NULL);
eina_iterator_free(it);
eina_array_free(array);
eina_shutdown();
}
static void
eina_bench_list_4evas_render(int request)
{
Eina_List *list = NULL;
Eina_List *tmp;
Eina_Bench_Object *ebo;
int i;
int j;
eina_init();
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
list = eina_list_prepend(list, ebo);
}
if (i == 500)
while (list)
{
free(eina_list_data_get(list));
list = eina_list_remove_list(list, list);
}
else if (i % 30 == 0)
{
tmp = list;
while (tmp)
{
Eina_List *reminder = tmp;
ebo = eina_list_data_get(reminder);
tmp = eina_list_next(tmp);
if (ebo->keep == EINA_FALSE)
{
list = eina_list_remove_list(list, reminder);
free(ebo);
}
}
}
for (tmp = list; tmp; tmp = eina_list_next(tmp))
{
ebo = eina_list_data_get(tmp);
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
}
}
while (list)
{
free(eina_list_data_get(list));
list = eina_list_remove_list(list, list);
}
eina_shutdown();
}
static void
eina_bench_list_4evas_render_iterator(int request)
{
Eina_List *list = NULL;
Eina_List *tmp;
Eina_Bench_Object *ebo;
Eina_Iterator *it;
int i;
int j;
eina_init();
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
list = eina_list_prepend(list, ebo);
}
if (i == 500)
while (list)
{
free(eina_list_data_get(list));
list = eina_list_remove_list(list, list);
}
else if (i % 30 == 0)
{
tmp = list;
while (tmp)
{
Eina_List *reminder = tmp;
ebo = eina_list_data_get(reminder);
tmp = eina_list_next(tmp);
if (ebo->keep == EINA_FALSE)
{
list = eina_list_remove_list(list, reminder);
free(ebo);
}
}
}
it = eina_list_iterator_new(list);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_ebo_rand), NULL);
eina_iterator_free(it);
}
while (list)
{
free(eina_list_data_get(list));
list = eina_list_remove_list(list, list);
}
eina_shutdown();
}
static void
eina_bench_inlist_4evas_render(int request)
{
Eina_Inlist *head = NULL;
Eina_Inlist *tmp;
Eina_Bench_Object *ebo;
int i;
int j;
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
head = eina_inlist_prepend(head, EINA_INLIST_GET(ebo));
}
if (i == 500)
while (head)
{
tmp = head;
head = head->next;
free(tmp);
}
else if (i % 30 == 0)
{
tmp = head;
while(tmp)
{
ebo = (Eina_Bench_Object *)tmp;
tmp = tmp->next;
if (ebo->keep == EINA_FALSE)
{
head = eina_inlist_remove(head, EINA_INLIST_GET(ebo));
free(ebo);
}
}
}
EINA_INLIST_FOREACH(head, ebo)
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
}
while (head)
{
tmp = head;
head = head->next;
free(tmp);
}
}
static void
eina_bench_inlist_4evas_render_iterator(int request)
{
Eina_Inlist *head = NULL;
Eina_Inlist *tmp;
Eina_Bench_Object *ebo;
Eina_Iterator *it;
int i;
int j;
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
head = eina_inlist_prepend(head, EINA_INLIST_GET(ebo));
}
if (i == 500)
while (head)
{
tmp = head;
head = head->next;
free(tmp);
}
else if (i % 30 == 0)
{
tmp = head;
while(tmp)
{
ebo = (Eina_Bench_Object *)tmp;
tmp = tmp->next;
if (ebo->keep == EINA_FALSE)
{
head = eina_inlist_remove(head, EINA_INLIST_GET(ebo));
free(ebo);
}
}
}
it = eina_inlist_iterator_new(head);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_ebo_rand), NULL);
eina_iterator_free(it);
}
while (head)
{
tmp = head;
head = head->next;
free(tmp);
}
}
#ifdef EINA_BENCH_HAVE_GLIB
static void
eina_bench_glist_4evas_render(int request)
{
GList *list = NULL;
GList *tmp;
Eina_Bench_Object *ebo;
int i;
int j;
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
list = g_list_prepend(list, ebo);
}
if (i == 500)
while (list)
{
free(list->data);
list = g_list_delete_link(list, list);
}
else if (i % 30 == 0)
{
tmp = list;
while (tmp)
{
GList *reminder = tmp;
ebo = reminder->data;
tmp = g_list_next(tmp);
if (ebo->keep == EINA_FALSE)
{
list = g_list_delete_link(list, reminder);
free(ebo);
}
}
}
for (tmp = list; tmp; tmp = g_list_next(tmp))
{
ebo = tmp->data;
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
}
}
while (list)
{
free(list->data);
list = g_list_delete_link(list, list);
}
}
static void
eina_bench_gptrarray_4evas_render(int request)
{
GPtrArray *array = NULL;
Eina_Bench_Object *ebo;
unsigned int j;
int i;
array = g_ptr_array_new();
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < (unsigned int)request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
g_ptr_array_add(array, ebo);
}
if (i == 500)
{
for (j = 0; j < array->len; ++j)
free(g_ptr_array_index(array, j));
g_ptr_array_remove_range(array, 0, array->len);
}
else if (i % 30 == 0)
for (j = 0; j < array->len; )
{
ebo = g_ptr_array_index(array, j);
if (ebo->keep == EINA_FALSE)
free(g_ptr_array_remove_index_fast(array, j));
else
j++;
}
for (j = 0; j < array->len; ++j)
{
ebo = g_ptr_array_index(array, j);
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
}
}
for (j = 0; j < array->len; ++j)
free(g_ptr_array_index(array, j));
g_ptr_array_free(array, TRUE);
}
#endif
static void
eina_bench_evas_list_4evas_render(int request)
{
Evas_List *list = NULL;
Evas_List *tmp;
Eina_Bench_Object *ebo;
int i;
int j;
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
list = evas_list_prepend(list, ebo);
}
if (i == 500)
while (list)
{
free(evas_list_data(list));
list = evas_list_remove_list(list, list);
}
else if (i % 30 == 0)
{
tmp = list;
while (tmp)
{
Evas_List *reminder = tmp;
ebo = evas_list_data(reminder);
tmp = evas_list_next(tmp);
if (ebo->keep == EINA_FALSE)
{
list = evas_list_remove_list(list, reminder);
free(ebo);
}
}
}
for (tmp = list; tmp; tmp = evas_list_next(tmp))
{
ebo = evas_list_data(tmp);
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
}
}
while (list)
{
free(evas_list_data(list));
list = evas_list_remove_list(list, list);
}
}
static void
_eina_ecore_for_each_remove(void *value, void *user_data)
{
Eina_Bench_Object *ebo = value;
Ecore_List *list = user_data;
if (ebo->keep == EINA_FALSE)
ecore_list_remove_destroy(list);
}
static void
_eina_ecore_for_each_rand(void *value, __UNUSED__ void *user_data)
{
Eina_Bench_Object *ebo = value;
ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
}
static void
eina_bench_ecore_list_4evas_render(int request)
{
Ecore_List *list = NULL;
Eina_Bench_Object *ebo;
int i;
int j;
list = ecore_list_new();
ecore_list_free_cb_set(list, free);
for (i = 0; i < 1000; ++i)
{
for (j = 0; j < request; ++j)
{
ebo = malloc(sizeof (Eina_Bench_Object));
if (!ebo)
continue;
ebo->keep = rand() < (RAND_MAX / 2) ? EINA_TRUE : EINA_FALSE;
ecore_list_prepend(list, ebo);
}
if (i == 500)
ecore_list_clear(list);
else if (i % 30 == 0)
ecore_list_for_each(list, _eina_ecore_for_each_remove, list);
ecore_list_for_each(list, _eina_ecore_for_each_rand, list);
}
ecore_list_destroy(list);
}
void eina_bench_array(Eina_Benchmark *bench)
{
eina_benchmark_register(bench, "array-inline",
EINA_BENCHMARK(
eina_bench_array_4evas_render_inline), 200,
4000, 100);
eina_benchmark_register(bench, "array-iterator",
EINA_BENCHMARK(
eina_bench_array_4evas_render_iterator), 200,
4000, 100);
eina_benchmark_register(bench, "list",
EINA_BENCHMARK(
eina_bench_list_4evas_render), 200,
4000, 100);
eina_benchmark_register(bench, "list-iterator",
EINA_BENCHMARK(
eina_bench_list_4evas_render_iterator), 200,
4000, 100);
eina_benchmark_register(bench, "inlist",
EINA_BENCHMARK(
eina_bench_inlist_4evas_render), 200,
4000, 100);
eina_benchmark_register(bench, "inlist-iterator",
EINA_BENCHMARK(
eina_bench_inlist_4evas_render_iterator), 200,
4000, 100);
#ifdef EINA_BENCH_HAVE_GLIB
eina_benchmark_register(bench, "glist",
EINA_BENCHMARK(
eina_bench_glist_4evas_render), 200,
4000, 100);
eina_benchmark_register(bench, "gptrarray",
EINA_BENCHMARK(
eina_bench_gptrarray_4evas_render), 200,
4000, 100);
#endif
eina_benchmark_register(bench, "evas",
EINA_BENCHMARK(
eina_bench_evas_list_4evas_render), 200,
4000, 100);
/* eina_benchmark_register(bench, "ecore", */
/* EINA_BENCHMARK( */
/* eina_bench_ecore_list_4evas_render), 200, */
/* 1000, 100); */
}

View File

@ -0,0 +1,183 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#ifdef EINA_BENCH_HAVE_GLIB
# include <glib.h>
#endif
#include "eina_bench.h"
#include "eina_convert.h"
static void
eina_bench_convert_itoa_10(int request)
{
char tmp[128];
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
eina_convert_itoa(rand(), tmp);
}
}
static void
eina_bench_convert_itoa_16(int request)
{
char tmp[128];
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
eina_convert_xtoa(rand(), tmp);
}
}
static void
eina_bench_convert_snprintf_10(int request)
{
char tmp[128];
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
snprintf(tmp, 128, "%i", rand());
}
}
static void
eina_bench_convert_snprintf_x(int request)
{
char tmp[128];
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
snprintf(tmp, 128, "%x", rand());
}
}
static void
eina_bench_convert_snprintf_a(int request)
{
char tmp[128];
double r;
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
r = 10000 * (rand() / ((double)RAND_MAX + 1));
snprintf(tmp, 128, "%a", r);
sscanf(tmp, "%la", &r);
}
}
static void
eina_bench_convert_dtoa(int request)
{
char tmp[128];
long long m;
long e;
double r;
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
r = 10000 * (rand() / ((double)RAND_MAX + 1));
eina_convert_dtoa(r, tmp);
eina_convert_atod(tmp, 128, &m, &e);
r = ldexp((double)m, e);
}
}
#ifdef EINA_BENCH_HAVE_GLIB
static void
eina_bench_convert_gstrtod(int request)
{
char tmp[128];
double r;
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
r = 10000 * (rand() / ((double)RAND_MAX + 1));
g_ascii_dtostr(tmp, 128, r);
r = g_ascii_strtod(tmp, NULL);
}
}
#endif
void eina_bench_convert(Eina_Benchmark *bench)
{
eina_benchmark_register(bench, "itoa 10",
EINA_BENCHMARK(
eina_bench_convert_itoa_10), 1000, 200000,
500);
eina_benchmark_register(bench, "itoa 16",
EINA_BENCHMARK(
eina_bench_convert_itoa_16), 1000, 200000,
500);
eina_benchmark_register(bench, "snprintf 10",
EINA_BENCHMARK(
eina_bench_convert_snprintf_10), 1000, 200000,
500);
eina_benchmark_register(bench, "snprintf 16",
EINA_BENCHMARK(
eina_bench_convert_snprintf_x), 1000, 200000,
500);
eina_benchmark_register(bench, "snprintf a",
EINA_BENCHMARK(
eina_bench_convert_snprintf_a), 1000, 200000,
500);
eina_benchmark_register(bench, "dtoa",
EINA_BENCHMARK(
eina_bench_convert_dtoa), 1000, 200000,
500);
#ifdef EINA_BENCH_HAVE_GLIB
eina_benchmark_register(bench, "gstrtod",
EINA_BENCHMARK(
eina_bench_convert_gstrtod), 1000, 200000,
500);
#endif
}

View File

@ -0,0 +1,426 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifdef EINA_BENCH_HAVE_GLIB
# include <glib.h>
#endif
#include "Evas_Data.h"
#include "Ecore_Data.h"
#include "eina_hash.h"
#include "eina_array.h"
#include "eina_bench.h"
#include "eina_rbtree.h"
#include "eina_convert.h"
typedef struct _Eina_Bench_Rbtree Eina_Bench_Rbtree;
struct _Eina_Bench_Rbtree
{
Eina_Rbtree node;
char key[10];
int value;
};
static Eina_Rbtree_Direction
_eina_bench_rbtree_cmp(const Eina_Bench_Rbtree *left,
const Eina_Bench_Rbtree *right,
__UNUSED__ void *data)
{
if (!left)
return EINA_RBTREE_RIGHT;
if (!right)
return EINA_RBTREE_LEFT;
return strcmp(left->key,
right->key) < 0 ? EINA_RBTREE_LEFT : EINA_RBTREE_RIGHT;
}
static inline int
_eina_bench_rbtree_key(const Eina_Bench_Rbtree *node,
const char *key,
int length,
__UNUSED__ void *data)
{
return strncmp(node->key, key, length);
}
static void
_eina_bench_rbtree_free(Eina_Rbtree *node, __UNUSED__ void *data)
{
free(node);
}
static void
eina_bench_lookup_rbtree(int request)
{
Eina_Rbtree *root = NULL;
int i;
int j;
for (i = 0; i < request; ++i)
{
Eina_Bench_Rbtree *tmp;
tmp = malloc(sizeof (Eina_Bench_Rbtree));
if (!tmp)
continue;
tmp->value = i;
eina_convert_itoa(i, tmp->key);
root = eina_rbtree_inline_insert(root,
&tmp->node,
EINA_RBTREE_CMP_NODE_CB(
_eina_bench_rbtree_cmp),
NULL);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < request; ++i)
{
Eina_Rbtree *tmp;
char tmp_key[10];
eina_convert_itoa(rand() % request, tmp_key);
tmp = eina_rbtree_inline_lookup(root,
tmp_key,
10,
EINA_RBTREE_CMP_KEY_CB(
_eina_bench_rbtree_key),
NULL);
}
eina_rbtree_delete(root, EINA_RBTREE_FREE_CB(_eina_bench_rbtree_free), NULL);
}
static void
eina_bench_lookup_superfast(int request)
{
Eina_Hash *hash = NULL;
int *tmp_val;
unsigned int i;
unsigned int j;
hash = eina_hash_string_superfast_new(free);
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
tmp_val = malloc(sizeof (int));
if (!tmp_val)
continue;
eina_convert_itoa(i, tmp_key);
*tmp_val = i;
eina_hash_add(hash, tmp_key, tmp_val);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
eina_convert_itoa(rand() % request, tmp_key);
tmp_val = eina_hash_find(hash, tmp_key);
}
eina_hash_free(hash);
}
static void
eina_bench_lookup_djb2(int request)
{
Eina_Hash *hash = NULL;
int *tmp_val;
unsigned int i;
unsigned int j;
hash = eina_hash_string_djb2_new(free);
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
tmp_val = malloc(sizeof (int));
if (!tmp_val)
continue;
eina_convert_itoa(i, tmp_key);
*tmp_val = i;
eina_hash_add(hash, tmp_key, tmp_val);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
eina_convert_itoa(rand() % request, tmp_key);
tmp_val = eina_hash_find(hash, tmp_key);
}
eina_hash_free(hash);
}
typedef struct _Eina_Bench_DJB2 Eina_Bench_DJB2;
struct _Eina_Bench_DJB2
{
char *key;
int value;
};
static void
eina_bench_lookup_djb2_inline(int request)
{
Eina_Hash *hash = NULL;
Eina_Bench_DJB2 *elm;
unsigned int i;
unsigned int j;
hash = eina_hash_string_djb2_new(free);
for (i = 0; i < (unsigned int)request; ++i)
{
int length;
elm = malloc(sizeof (Eina_Bench_DJB2) + 10);
if (!elm)
continue;
elm->key = (char *)(elm + 1);
length = eina_convert_itoa(i, elm->key) + 1;
elm->value = i;
eina_hash_direct_add_by_hash(hash, elm->key, length,
eina_hash_djb2(elm->key, length), elm);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
int length = 6;
length = eina_convert_itoa(rand() % request, tmp_key) + 1;
elm =
eina_hash_find_by_hash(hash, tmp_key, length,
eina_hash_djb2(tmp_key, length));
}
eina_hash_free(hash);
}
#ifdef EINA_BENCH_HAVE_GLIB
typedef struct _Eina_Bench_Glib Eina_Bench_Glib;
struct _Eina_Bench_Glib
{
char *key;
int value;
};
static void
eina_bench_lookup_ghash(int request)
{
Eina_Bench_Glib *elm;
GHashTable *hash;
unsigned int i;
unsigned int j;
hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free);
for (i = 0; i < (unsigned int)request; ++i)
{
elm = malloc(sizeof (Eina_Bench_Glib) + 10);
if (!elm)
continue;
elm->key = (char *)(elm + 1);
eina_convert_itoa(i, elm->key);
elm->value = i;
g_hash_table_insert(hash, elm->key, elm);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
eina_convert_itoa(rand() % request, tmp_key);
elm = g_hash_table_lookup(hash, tmp_key);
}
g_hash_table_destroy(hash);
}
#endif
static void
eina_bench_lookup_evas(int request)
{
Evas_Hash *hash = NULL;
Eina_Array *array = NULL;
int *tmp_val;
Eina_Array_Iterator it;
unsigned int i;
unsigned int j;
array = eina_array_new(1000);
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
tmp_val = malloc(sizeof (int));
if (!tmp_val)
continue;
eina_convert_itoa(i, tmp_key);
*tmp_val = i;
hash = evas_hash_add(hash, tmp_key, tmp_val);
eina_array_push(array, tmp_val);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
eina_convert_itoa(rand() % request, tmp_key);
tmp_val = evas_hash_find(hash, tmp_key);
}
evas_hash_free(hash);
EINA_ARRAY_ITER_NEXT(array, i, tmp_val, it)
free(tmp_val);
eina_array_free(array);
}
typedef struct _Eina_Bench_Ecore Eina_Bench_Ecore;
struct _Eina_Bench_Ecore
{
char *key;
int value;
};
static void
eina_bench_lookup_ecore(int request)
{
Ecore_Hash *hash = NULL;
Eina_Bench_Ecore *elm;
unsigned int i;
unsigned int j;
hash = ecore_hash_new(ecore_str_hash, ecore_str_compare);
ecore_hash_free_key_cb_set(hash, NULL);
ecore_hash_free_value_cb_set(hash, free);
for (i = 0; i < (unsigned int)request; ++i)
{
elm = malloc(sizeof (Eina_Bench_Ecore) + 10);
if (!elm)
continue;
elm->key = (char *)(elm + 1);
eina_convert_itoa(i, elm->key);
elm->value = i;
ecore_hash_set(hash, elm->key, elm);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < (unsigned int)request; ++i)
{
char tmp_key[10];
eina_convert_itoa(rand() % request, tmp_key);
elm = ecore_hash_get(hash, tmp_key);
}
ecore_hash_destroy(hash);
}
void eina_bench_hash(Eina_Benchmark *bench)
{
eina_benchmark_register(bench, "superfast-lookup",
EINA_BENCHMARK(
eina_bench_lookup_superfast), 10, 3000, 10);
eina_benchmark_register(bench, "djb2-lookup",
EINA_BENCHMARK(
eina_bench_lookup_djb2), 10, 3000, 10);
eina_benchmark_register(bench, "djb2-lookup-inline",
EINA_BENCHMARK(
eina_bench_lookup_djb2_inline), 10, 3000, 10);
eina_benchmark_register(bench, "rbtree",
EINA_BENCHMARK(
eina_bench_lookup_rbtree), 10, 3000, 10);
#ifdef EINA_BENCH_HAVE_GLIB
eina_benchmark_register(bench, "ghash-lookup",
EINA_BENCHMARK(
eina_bench_lookup_ghash), 10, 3000, 10);
#endif
eina_benchmark_register(bench, "evas-lookup",
EINA_BENCHMARK(
eina_bench_lookup_evas), 10, 3000, 10);
eina_benchmark_register(bench, "ecore-lookup",
EINA_BENCHMARK(
eina_bench_lookup_ecore), 10, 3000, 10);
}

View File

@ -0,0 +1,188 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef EINA_BENCH_HAVE_GLIB
# include <glib.h>
#endif
#include "eina_bench.h"
#include "Eina.h"
static void
_eina_mempool_bench(Eina_Mempool *mp, int request)
{
Eina_Array *array;
int i;
int j;
eina_init();
array = eina_array_new(32);
for (i = 0; i < 100; ++i)
{
for (j = 0; j < request; ++j)
{
eina_array_push(array, eina_mempool_malloc(mp, sizeof (int)));
}
for (j = 0; j < request; ++j)
{
eina_mempool_free(mp, eina_array_pop(array));
}
}
eina_array_free(array);
eina_shutdown();
}
#ifdef EINA_BUILD_CHAINED_POOL
static void
eina_mempool_chained_mempool(int request)
{
Eina_Mempool *mp;
mp = eina_mempool_add("chained_mempool", "test", NULL, sizeof (int), 256);
_eina_mempool_bench(mp, request);
eina_mempool_del(mp);
}
#endif
#ifdef EINA_BUILD_PASS_THROUGH
static void
eina_mempool_pass_through(int request)
{
Eina_Mempool *mp;
mp = eina_mempool_add("pass_through", "test", NULL, sizeof (int), 8, 0);
_eina_mempool_bench(mp, request);
eina_mempool_del(mp);
}
#endif
#ifdef EINA_BUILD_FIXED_BITMAP
static void
eina_mempool_fixed_bitmap(int request)
{
Eina_Mempool *mp;
mp = eina_mempool_add("fixed_bitmap", "test", NULL, sizeof (int));
_eina_mempool_bench(mp, request);
eina_mempool_del(mp);
}
#endif
#ifdef EINA_BUILD_EMEMOA_FIXED
static void
eina_mempool_ememoa_fixed(int request)
{
Eina_Mempool *mp;
mp = eina_mempool_add("ememoa_fixed", "test", NULL, sizeof (int), 8, 0);
_eina_mempool_bench(mp, request);
eina_mempool_del(mp);
}
#endif
#ifdef EINA_BUILD_EMEMOA_UNKNOWN
static void
eina_mempool_ememoa_unknown(int request)
{
Eina_Mempool *mp;
mp = eina_mempool_add("ememoa_unknown",
"test",
NULL,
0,
2,
sizeof (int),
8,
sizeof (int) * 2,
8);
_eina_mempool_bench(mp, request);
eina_mempool_del(mp);
}
#endif
#ifdef EINA_BENCH_HAVE_GLIB
static void
eina_mempool_glib(int request)
{
Eina_Array *array;
int i;
int j;
eina_init();
array = eina_array_new(32);
for (i = 0; i < 100; ++i)
{
for (j = 0; j < request; ++j)
{
eina_array_push(array, g_slice_alloc(sizeof (int)));
}
for (j = 0; j < request; ++j)
{
g_slice_free1(sizeof (int), eina_array_pop(array));
}
}
eina_array_free(array);
eina_shutdown();
}
#endif
void
eina_bench_mempool(Eina_Benchmark *bench)
{
#ifdef EINA_BUILD_CHAINED_POOL
eina_benchmark_register(bench, "chained mempool",
EINA_BENCHMARK(
eina_mempool_chained_mempool), 10, 1000, 10);
#endif
#ifdef EINA_BUILD_PASS_THROUGH
eina_benchmark_register(bench, "pass through",
EINA_BENCHMARK(
eina_mempool_pass_through), 10, 1000, 10);
#endif
#ifdef EINA_BUILD_FIXED_BITMAP
eina_benchmark_register(bench, "fixed bitmap",
EINA_BENCHMARK(
eina_mempool_fixed_bitmap), 10, 1000, 10);
#endif
#ifdef EINA_BUILD_EMEMOA_FIXED
eina_benchmark_register(bench, "ememoa fixed",
EINA_BENCHMARK(
eina_mempool_ememoa_fixed), 10, 1000, 10);
#endif
#ifdef EINA_BUILD_EMEMOA_UNKNOWN
eina_benchmark_register(bench, "ememoa unknown",
EINA_BENCHMARK(
eina_mempool_ememoa_unknown), 10, 1000, 10);
#endif
#ifdef EINA_BENCH_HAVE_GLIB
eina_benchmark_register(bench, "gslice",
EINA_BENCHMARK(
eina_mempool_glib), 10, 1000, 10);
#endif
}

View File

@ -0,0 +1,318 @@
/* EINA - EFL data type library
* Copyright (C) 2010 Cedric BAIL
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#define WIDTH 720
#define HEIGHT 576
#include "eina_main.h"
#include "eina_mempool.h"
#include "eina_rectangle.h"
#include "eina_quadtree.h"
#include "eina_list.h"
#include "eina_bench.h"
static void
eina_bench_render_loop(int request)
{
Eina_List *objects = NULL;
Eina_Rectangle *r;
int i;
int j;
eina_init();
for (i = 0; i < request; ++i)
objects = eina_list_append(objects,
eina_rectangle_new((rand() * WIDTH) / RAND_MAX,
(rand() *
HEIGHT) / RAND_MAX,
(rand() * WIDTH /
2) / RAND_MAX,
(rand() * HEIGHT /
2) / RAND_MAX));
for (j = 0; j < 100; ++j)
{
Eina_Rectangle *collide;
Eina_List *collided = NULL;
Eina_List *changed = NULL;
Eina_List *l;
/* Delete 25% of all objects */
i = request * 25 / 100;
for (; i > 0; --i)
{
eina_rectangle_free(eina_list_data_get(objects));
objects = eina_list_remove_list(objects, objects);
}
/* Add them back */
i = request * 25 / 100;
for (; i > 0; --i)
{
r = eina_rectangle_new((rand() * WIDTH) / RAND_MAX,
(rand() * HEIGHT) / RAND_MAX,
(rand() * WIDTH / 3) / RAND_MAX,
(rand() * HEIGHT / 3) / RAND_MAX);
objects = eina_list_prepend(objects, r);
changed = eina_list_append(changed, r);
}
/* Do one collide search */
collide = eina_rectangle_new((rand() * WIDTH) / RAND_MAX,
(rand() * HEIGHT) / RAND_MAX,
(rand() * WIDTH / 4) / RAND_MAX,
(rand() * HEIGHT / 4) / RAND_MAX);
EINA_LIST_FOREACH(objects, l, r)
if (eina_rectangles_intersect(r, collide))
collided = eina_list_append(collided, r);
collided = eina_list_free(collided);
eina_rectangle_free(collide);
/* Modify 50% of all objects */
i = request * 50 / 100;
for (; i > 0; --i)
{
r = eina_list_data_get(eina_list_last(objects));
objects = eina_list_remove_list(objects, eina_list_last(objects));
r->x = (rand() * WIDTH) / RAND_MAX;
r->y = (rand() * HEIGHT) / RAND_MAX;
r->w = (rand() * WIDTH / 3) / RAND_MAX;
r->h = (rand() * HEIGHT / 3) / RAND_MAX;
objects = eina_list_prepend(objects, r);
changed = eina_list_append(changed, r);
}
/* Emulating the render loop by colliding all modified
object with all intersecting object */
EINA_LIST_FREE(changed, r)
{
EINA_LIST_FOREACH(objects, l, collide)
if (r != collide && eina_rectangles_intersect(collide, r))
collided = eina_list_append(collided, collide);
collided = eina_list_append(collided, r);
}
/* Ok, we compute it, now it's done */
collided = eina_list_free(collided);
}
EINA_LIST_FREE(objects, r)
eina_rectangle_free(r);
eina_shutdown();
}
typedef struct _Eina_Bench_Quad Eina_Bench_Quad;
struct _Eina_Bench_Quad
{
Eina_Rectangle r;
Eina_QuadTree_Item *item;
};
static Eina_Quad_Direction
_eina_bench_quadtree_vertical(const void *object, size_t middle)
{
const Eina_Bench_Quad *b = object;
size_t y;
y = b->r.y < 0 ? 0 : (size_t)b->r.y;
if (y + b->r.h < middle)
return EINA_QUAD_LEFT;
if (y > middle)
return EINA_QUAD_RIGHT;
return EINA_QUAD_BOTH;
}
static Eina_Quad_Direction
_eina_bench_quadtree_horizontal(const void *object, size_t middle)
{
const Eina_Bench_Quad *b = object;
size_t x;
x = b->r.x < 0 ? 0 : (size_t)b->r.x;
if (x + b->r.w < middle)
return EINA_QUAD_LEFT;
if (x > middle)
return EINA_QUAD_RIGHT;
return EINA_QUAD_BOTH;
}
static void
eina_bench_quadtree_render_loop(int request)
{
Eina_List *objects = NULL;
Eina_Inlist *possibility;
Eina_Bench_Quad *b;
Eina_QuadTree *q;
Eina_Mempool *mp;
int i;
int j;
eina_init();
mp = eina_mempool_add("chained_mempool", "bench-quad", NULL,
sizeof (Eina_Bench_Quad), 320);
q = eina_quadtree_new(WIDTH, HEIGHT,
_eina_bench_quadtree_vertical,
_eina_bench_quadtree_horizontal);
/* Create requested object */
for (i = 0; i < request; ++i)
{
b = eina_mempool_malloc(mp, sizeof (Eina_Bench_Quad));
EINA_RECTANGLE_SET(&b->r,
(rand() * WIDTH) / RAND_MAX,
(rand() * HEIGHT) / RAND_MAX,
(rand() * WIDTH / 2) / RAND_MAX,
(rand() * HEIGHT / 2) / RAND_MAX);
b->item = eina_quadtree_add(q, b);
objects = eina_list_append(objects, b);
}
for (j = 0; j < 100; ++j)
{
Eina_Bench_Quad *collide;
Eina_List *changed = NULL;
Eina_List *collided = NULL;
/* Delete 25% of all objects */
i = request * 25 / 100;
for (; i > 0; --i)
{
b = eina_list_data_get(objects);
eina_quadtree_del(b->item);
eina_mempool_free(mp, b);
objects = eina_list_remove_list(objects, objects);
}
/* Add them back */
i = request * 25 / 100;
for (; i > 0; --i)
{
b = eina_mempool_malloc(mp, sizeof (Eina_Bench_Quad));
EINA_RECTANGLE_SET(&b->r,
(rand() * WIDTH) / RAND_MAX,
(rand() * HEIGHT) / RAND_MAX,
(rand() * WIDTH / 3) / RAND_MAX,
(rand() * HEIGHT / 3) / RAND_MAX);
b->item = eina_quadtree_add(q, b);
objects = eina_list_prepend(objects, b);
changed = eina_list_append(changed, b);
}
/* Do one collide search */
collide = eina_mempool_malloc(mp, sizeof (Eina_Bench_Quad));
EINA_RECTANGLE_SET(&collide->r,
(rand() * WIDTH) / RAND_MAX,
(rand() * HEIGHT) / RAND_MAX,
(rand() * WIDTH / 4) / RAND_MAX,
(rand() * HEIGHT / 4) / RAND_MAX);
possibility = eina_quadtree_collide(q,
collide->r.x, collide->r.y,
collide->r.w, collide->r.h);
while (possibility)
{
b = eina_quadtree_object(possibility);
possibility = possibility->next;
if (eina_rectangles_intersect(&b->r, &collide->r))
collided = eina_list_append(collided, b);
}
collided = eina_list_free(collided);
eina_mempool_free(mp, collide);
/* Modify 50% of all objects */
i = request * 50 / 100;
for (; i > 0; --i)
{
b = eina_list_data_get(eina_list_last(objects));
objects = eina_list_remove_list(objects, eina_list_last(objects));
b->r.x = (rand() * WIDTH) / RAND_MAX;
b->r.y = (rand() * HEIGHT) / RAND_MAX;
b->r.w = (rand() * WIDTH / 3) / RAND_MAX;
b->r.h = (rand() * HEIGHT / 3) / RAND_MAX;
eina_quadtree_change(b->item);
objects = eina_list_prepend(objects, b);
changed = eina_list_append(changed, b);
}
/* Emulating the render loop by colliding all modified
object with all intersecting object */
EINA_LIST_FREE(changed, b)
{
possibility = eina_quadtree_collide(q,
b->r.x, b->r.y, b->r.w, b->r.h);
while (possibility)
{
collide = eina_quadtree_object(possibility);
possibility = possibility->next;
if (collide != b &&
eina_rectangles_intersect(&b->r, &collide->r))
collided = eina_list_append(collided, collide);
}
collided = eina_list_append(collided, b);
}
/* Ok, we compute it, now it's done */
collided = eina_list_free(collided);
}
EINA_LIST_FREE(objects, b)
{
eina_quadtree_del(b->item);
eina_mempool_free(mp, b);
}
eina_mempool_del(mp);
eina_quadtree_free(q);
eina_shutdown();
}
void
eina_bench_quadtree(Eina_Benchmark *bench)
{
eina_benchmark_register(bench, "collide-all",
EINA_BENCHMARK(eina_bench_render_loop),
100, 1500, 50);
eina_benchmark_register(bench, "collide-quad-tree",
EINA_BENCHMARK(eina_bench_quadtree_render_loop),
100, 1500, 50);
}

View File

@ -0,0 +1,76 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "eina_bench.h"
#include "Eina.h"
static void
eina_bench_eina_rectangle_pool(int request)
{
Eina_Rectangle_Pool *pool;
Eina_Rectangle *rect;
Eina_List *list = NULL;
int i;
eina_init();
eina_init();
pool = eina_rectangle_pool_new(2048, 2048);
if (!pool)
return;
for (i = 0; i < request; ++i)
{
rect = NULL;
while (!rect)
{
rect = eina_rectangle_pool_request(pool, i & 0xFF, 256 - (i & 0xFF));
if (!rect)
{
rect = eina_list_data_get(list);
list = eina_list_remove_list(list, list);
if (rect)
eina_rectangle_pool_release(rect);
}
else
list = eina_list_append(list, rect);
if (!(i & 0xFF))
break;
}
}
eina_rectangle_pool_free(pool);
eina_list_free(list);
eina_shutdown();
}
void eina_bench_rectangle_pool(Eina_Benchmark *bench)
{
eina_benchmark_register(bench, "eina",
EINA_BENCHMARK(
eina_bench_eina_rectangle_pool), 10, 4000, 100);
}

View File

@ -0,0 +1,222 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#ifdef EINA_BENCH_HAVE_GLIB
# include <glib.h>
#endif
#include "Evas_Data.h"
#include "Ecore_Data.h"
#include "eina_bench.h"
#include "eina_convert.h"
#include "eina_list.h"
#include "eina_main.h"
static int
_eina_cmp_str(const char *a, const char *b)
{
return strcmp(a, b);
}
static void
eina_bench_sort_eina(int request)
{
Eina_List *list = NULL;
int i;
eina_init();
srand(time(NULL));
for (i = 0; i < request; ++i)
{
char buffer[10];
eina_convert_itoa(rand() % request, buffer);
list = eina_list_prepend(list, strdup(buffer));
}
list = eina_list_sort(list, -1, EINA_COMPARE_CB(_eina_cmp_str));
while (list)
{
free(eina_list_data_get(list));
list = eina_list_remove_list(list, list);
}
eina_shutdown();
}
static void
eina_bench_sort_evas(int request)
{
Evas_List *list = NULL;
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
char buffer[10];
eina_convert_itoa(rand() % request, buffer);
list = evas_list_prepend(list, strdup(buffer));
}
list = evas_list_sort(list, -1, (void *)_eina_cmp_str);
while (list)
{
free(evas_list_data(list));
list = evas_list_remove_list(list, list);
}
}
#ifdef EINA_BENCH_HAVE_GLIB
static void
eina_bench_sort_glist(int request)
{
GList *list = NULL;
int i;
srand(time(NULL));
for (i = 0; i < request; ++i)
{
char buffer[10];
eina_convert_itoa(rand() % request, buffer);
list = g_list_prepend(list, strdup(buffer));
}
list = g_list_sort(list, (void *)_eina_cmp_str);
while (list)
{
free(list->data);
list = g_list_delete_link(list, list);
}
}
#endif
static void
eina_bench_sort_ecore_default(int request)
{
Ecore_List *list = NULL;
int i;
list = ecore_list_new();
ecore_list_free_cb_set(list, free);
for (i = 0; i < request; ++i)
{
char buffer[10];
eina_convert_itoa(rand() % request, buffer);
ecore_list_prepend(list, strdup(buffer));
}
ecore_list_sort(list, ECORE_COMPARE_CB(_eina_cmp_str), 0);
ecore_list_destroy(list);
}
static void
eina_bench_sort_ecore_merge(int request)
{
Ecore_List *list = NULL;
int i;
list = ecore_list_new();
ecore_list_free_cb_set(list, free);
for (i = 0; i < request; ++i)
{
char buffer[10];
eina_convert_itoa(rand() % request, buffer);
ecore_list_prepend(list, strdup(buffer));
}
ecore_list_mergesort(list, ECORE_COMPARE_CB(_eina_cmp_str), 0);
ecore_list_destroy(list);
}
static void
eina_bench_sort_ecore_heap(int request)
{
Ecore_List *list = NULL;
int i;
list = ecore_list_new();
ecore_list_free_cb_set(list, free);
for (i = 0; i < request; ++i)
{
char buffer[10];
eina_convert_itoa(rand() % request, buffer);
ecore_list_prepend(list, strdup(buffer));
}
ecore_list_heapsort(list, ECORE_COMPARE_CB(_eina_cmp_str), 0);
ecore_list_destroy(list);
}
void eina_bench_sort(Eina_Benchmark *bench)
{
eina_benchmark_register(bench, "eina",
EINA_BENCHMARK(
eina_bench_sort_eina), 10, 10000, 100);
#ifdef EINA_BENCH_HAVE_GLIB
eina_benchmark_register(bench, "glist",
EINA_BENCHMARK(
eina_bench_sort_glist), 10, 10000, 100);
#endif
eina_benchmark_register(bench, "ecore",
EINA_BENCHMARK(
eina_bench_sort_ecore_default), 10, 10000, 100);
eina_benchmark_register(bench, "ecore-merge",
EINA_BENCHMARK(
eina_bench_sort_ecore_merge), 10, 10000, 100);
eina_benchmark_register(bench, "ecore-heap",
EINA_BENCHMARK(
eina_bench_sort_ecore_heap), 10, 10000, 100);
eina_benchmark_register(bench, "evas",
EINA_BENCHMARK(
eina_bench_sort_evas), 10, 10000, 100);
}

View File

@ -0,0 +1,177 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#ifdef EINA_BENCH_HAVE_GLIB
# include <glib.h>
#endif
#include "Evas_Data.h"
#include "Ecore_Data.h"
#include "eina_stringshare.h"
#include "eina_bench.h"
#include "eina_convert.h"
#include "eina_main.h"
static void
eina_bench_stringshare_job(int request)
{
const char *tmp;
unsigned int j;
int i;
eina_init();
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(i, build + 7);
tmp = eina_stringshare_add(build);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(rand() % request, build + 7);
tmp = eina_stringshare_add(build);
}
eina_shutdown();
}
#ifdef EINA_BENCH_HAVE_GLIB
static void
eina_bench_stringchunk_job(int request)
{
GStringChunk *chunk;
unsigned int j;
int i;
chunk = g_string_chunk_new(4096);
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(i, build + 7);
g_string_chunk_insert_const(chunk, build);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(rand() % request, build + 7);
g_string_chunk_insert_const(chunk, build);
}
g_string_chunk_free(chunk);
}
#endif
static void
eina_bench_evas_job(int request)
{
const char *tmp;
unsigned int j;
int i;
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(i, build + 7);
tmp = evas_stringshare_add(build);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(rand() % request, build + 7);
tmp = evas_stringshare_add(build);
}
}
static void
eina_bench_ecore_job(int request)
{
const char *tmp;
unsigned int j;
int i;
ecore_string_init();
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(i, build + 7);
tmp = ecore_string_instance(build);
}
srand(time(NULL));
for (j = 0; j < 200; ++j)
for (i = 0; i < request; ++i)
{
char build[64] = "string_";
eina_convert_xtoa(rand() % request, build + 7);
tmp = ecore_string_instance(build);
}
ecore_string_shutdown();
}
void eina_bench_stringshare(Eina_Benchmark *bench)
{
eina_benchmark_register(bench, "stringshare",
EINA_BENCHMARK(
eina_bench_stringshare_job), 100, 20100, 500);
#ifdef EINA_BENCH_HAVE_GLIB
eina_benchmark_register(bench, "stringchunk (glib)",
EINA_BENCHMARK(
eina_bench_stringchunk_job), 100, 20100, 500);
#endif
eina_benchmark_register(bench, "stringshare (evas)",
EINA_BENCHMARK(
eina_bench_evas_job), 100, 20100, 500);
eina_benchmark_register(bench, "stringshare (ecore)",
EINA_BENCHMARK(
eina_bench_ecore_job), 100, 20100, 500);
}

View File

@ -0,0 +1,118 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#ifdef EINA_BENCH_HAVE_GLIB
# include <glib.h>
#endif
#include "Evas_Data.h"
#include "Ecore_Data.h"
#include "Eina.h"
#if EINA_ENABLE_BENCH_E17
typedef struct _Eina_Stringshare_Test Eina_Stringshare_Test;
struct _Eina_Stringshare_Test
{
const char *name;
int (*init)(void);
const char *(*add)(const char *str);
void (*del)(const char *str);
int (*shutdown)(void);
};
static const char *strings[30000];
static Eina_Stringshare_Test eina_str = {
"eina",
eina_init,
eina_stringshare_add,
eina_stringshare_del,
eina_shutdown
};
static Eina_Stringshare_Test evas_str = {
"evas",
/* evas_stringshare_init, */
evas_stringshare_add,
evas_stringshare_del
/* evas_stringshare_shutdown */
};
static Eina_Stringshare_Test ecore_str = {
"ecore",
ecore_string_init,
ecore_string_instance,
ecore_string_release,
ecore_string_shutdown
};
static Eina_Stringshare_Test *str[] = {
&eina_str,
&evas_str,
&ecore_str,
NULL
};
static void
eina_bench_e17_stringshare(Eina_Stringshare_Test *str)
{
Eina_Counter *cnt;
cnt = eina_counter_new(str->name);
eina_counter_start(cnt);
str->init();
#include "strlog"
str->shutdown();
eina_counter_stop(cnt, 1);
fprintf(stderr, "For `%s`:\n", str->name);
eina_counter_dump(cnt);
eina_counter_free(cnt);
}
#endif
void
eina_bench_e17(void)
{
#if EINA_ENABLE_BENCH_E17
int i;
eina_init();
for (i = 0; str[i]; ++i)
eina_bench_e17_stringshare(str[i]);
eina_shutdown();
#endif
}

View File

@ -0,0 +1,174 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "eina_suite.h"
#include "Eina.h"
#include <stdio.h>
#include <string.h>
typedef struct _Eina_Test_Case Eina_Test_Case;
struct _Eina_Test_Case
{
const char *test_case;
void (*build)(TCase *tc);
};
static const Eina_Test_Case etc[] = {
{ "FixedPoint", eina_test_fp },
{ "Array", eina_test_array },
{ "Binary Share", eina_test_binshare },
{ "String Share", eina_test_stringshare },
{ "UString Share", eina_test_ustringshare },
{ "Log", eina_test_log },
{ "Error", eina_test_error },
{ "Magic", eina_test_magic },
{ "Inlist", eina_test_inlist },
{ "Lazy alloc", eina_test_lalloc },
{ "Main", eina_test_main },
{ "Counter", eina_test_counter },
{ "Hash", eina_test_hash },
{ "List", eina_test_list },
{ "Iterator", eina_test_iterator },
{ "Accessor", eina_test_accessor },
{ "Module", eina_test_module },
{ "Convert", eina_test_convert },
{ "Rbtree", eina_test_rbtree },
{ "File", eina_test_file },
{ "Benchmark", eina_test_benchmark },
{ "Mempool", eina_test_mempool },
{ "Rectangle", eina_test_rectangle },
{ "Matrix Sparse", eina_test_matrixsparse },
{ "Eina Tiler", eina_test_tiler },
{ "Eina Strbuf", eina_test_strbuf },
{ "String", eina_test_str },
{ "Unicode String", eina_test_ustr },
{ "QuadTree", eina_test_quadtree },
{ "Sched", eina_test_sched },
{ NULL, NULL }
};
static void
_list_tests(void)
{
const Eina_Test_Case *itr = etc;
fputs("Available Test Cases:\n", stderr);
for (; itr->test_case; itr++)
fprintf(stderr, "\t%s\n", itr->test_case);
}
static Eina_Bool
_use_test(int argc, const char **argv, const char *test_case)
{
if (argc < 1)
return 1;
for (; argc > 0; argc--, argv++)
if (strcmp(test_case, *argv) == 0)
return 1;
return 0;
}
Suite *
eina_build_suite(int argc, const char **argv)
{
TCase *tc;
Suite *s;
int i;
s = suite_create("Eina");
for (i = 0; etc[i].test_case; ++i)
{
if (!_use_test(argc, argv, etc[i].test_case))
continue;
tc = tcase_create(etc[i].test_case);
etc[i].build(tc);
suite_add_tcase(s, tc);
tcase_set_timeout(tc, 0);
}
return s;
}
/* FIXME this is a copy from eina_test_mempool
* we should remove the duplication
*/
static Eina_Array *_modules;
static void _mempool_init(void)
{
eina_init();
/* force modules to be loaded in case they are not installed */
_modules = eina_module_list_get(NULL,
PACKAGE_BUILD_DIR "/src/modules",
EINA_TRUE,
NULL,
NULL);
eina_module_list_load(_modules);
}
static void _mempool_shutdown(void)
{
eina_module_list_free(_modules);
/* TODO delete the list */
eina_shutdown();
}
int
main(int argc, char **argv)
{
Suite *s;
SRunner *sr;
int i, failed_count;
for (i = 1; i < argc; i++)
if ((strcmp(argv[i], "-h") == 0) ||
(strcmp(argv[i], "--help") == 0))
{
fprintf(stderr, "Usage:\n\t%s [test_case1 .. [test_caseN]]\n",
argv[0]);
_list_tests();
return 0;
}
else if ((strcmp(argv[i], "-l") == 0) ||
(strcmp(argv[i], "--list") == 0))
{
_list_tests();
return 0;
}
s = eina_build_suite(argc - 1, (const char **)argv + 1);
sr = srunner_create(s);
_mempool_init();
srunner_run_all(sr, CK_ENV);
failed_count = srunner_ntests_failed(sr);
srunner_free(sr);
_mempool_shutdown();
return (failed_count == 0) ? 0 : 255;
}

View File

@ -0,0 +1,55 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EINA_SUITE_H_
#define EINA_SUITE_H_
#include <check.h>
void eina_test_stringshare(TCase *tc);
void eina_test_ustringshare(TCase *tc);
void eina_test_binshare(TCase *tc);
void eina_test_array(TCase *tc);
void eina_test_log(TCase *tc);
void eina_test_error(TCase *tc);
void eina_test_magic(TCase *tc);
void eina_test_inlist(TCase *tc);
void eina_test_lalloc(TCase *tc);
void eina_test_main(TCase *tc);
void eina_test_counter(TCase *tc);
void eina_test_hash(TCase *tc);
void eina_test_list(TCase *tc);
void eina_test_iterator(TCase *tc);
void eina_test_accessor(TCase *tc);
void eina_test_module(TCase *tc);
void eina_test_convert(TCase *tc);
void eina_test_rbtree(TCase *tc);
void eina_test_file(TCase *tc);
void eina_test_benchmark(TCase *tc);
void eina_test_mempool(TCase *tc);
void eina_test_rectangle(TCase *tc);
void eina_test_matrixsparse(TCase *tc);
void eina_test_tiler(TCase *tc);
void eina_test_strbuf(TCase *tc);
void eina_test_str(TCase *tc);
void eina_test_ustr(TCase *tc);
void eina_test_quadtree(TCase *tc);
void eina_test_fp(TCase *tc);
void eina_test_sched(TCase *tc);
#endif /* EINA_SUITE_H_ */

View File

@ -0,0 +1,243 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
static Eina_Bool
eina_accessor_check(__UNUSED__ const Eina_Array *array,
int *data, int *fdata)
{
fail_if(*fdata > *data);
*fdata = *data;
return EINA_TRUE;
}
START_TEST(eina_accessor_array_simple)
{
Eina_Accessor *it;
Eina_Array *ea;
int *tmp;
int i;
eina_init();
ea = eina_array_new(11);
fail_if(!ea);
for (i = 0; i < 200; ++i)
{
tmp = malloc(sizeof(int));
fail_if(!tmp);
*tmp = i;
eina_array_push(ea, tmp);
}
it = eina_array_accessor_new(ea);
fail_if(!it);
fail_if(eina_accessor_data_get(it, 100, (void **)&tmp) != EINA_TRUE);
fail_if(!tmp);
fail_if(*tmp != 100);
i = 50;
eina_accessor_over(it, EINA_EACH_CB(eina_accessor_check), 50, 100, &i);
fail_if(i != 99);
fail_if(eina_accessor_container_get(it) != ea);
eina_accessor_free(it);
eina_array_free(ea);
eina_shutdown();
}
END_TEST
typedef struct _Eina_Test_Inlist Eina_Test_Inlist;
struct _Eina_Test_Inlist
{
EINA_INLIST;
int i;
};
static Eina_Test_Inlist *
_eina_test_inlist_build(int i)
{
Eina_Test_Inlist *tmp;
tmp = malloc(sizeof(Eina_Test_Inlist));
fail_if(!tmp);
tmp->i = i;
return tmp;
}
static Eina_Bool
eina_accessor_inlist_data_check(__UNUSED__ const Eina_Inlist *in_list,
Eina_Test_Inlist *data,
int *fdata)
{
switch (*fdata)
{
case 0: fail_if(data->i != 3227); break;
case 1: fail_if(data->i != 1664); break;
}
(*fdata)++;
return EINA_TRUE;
}
START_TEST(eina_accessor_inlist_simple)
{
Eina_Inlist *lst = NULL;
Eina_Test_Inlist *tmp;
Eina_Test_Inlist *prev;
Eina_Accessor *it;
int i = 0;
tmp = _eina_test_inlist_build(42);
lst = eina_inlist_append(lst, EINA_INLIST_GET(tmp));
fail_if(!lst);
tmp = _eina_test_inlist_build(1664);
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst);
fail_if(!lst);
fail_if(((Eina_Test_Inlist *)lst)->i != 42);
prev = tmp;
tmp = _eina_test_inlist_build(3227);
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(
tmp), EINA_INLIST_GET(prev));
fail_if(!lst);
fail_if(((Eina_Test_Inlist *)lst)->i != 42);
tmp = _eina_test_inlist_build(27);
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), NULL);
tmp = _eina_test_inlist_build(81);
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), NULL);
tmp = _eina_test_inlist_build(7);
lst = eina_inlist_append(lst, EINA_INLIST_GET(tmp));
it = eina_inlist_accessor_new(lst);
fail_if(!it);
fail_if(eina_accessor_container_get(it) != lst);
eina_accessor_over(it, EINA_EACH_CB(eina_accessor_inlist_data_check), 2, 4, &i);
fail_if(eina_accessor_data_get(it, 5, (void **)&tmp) != EINA_TRUE);
fail_if(eina_accessor_data_get(it, 3, (void **)&tmp) != EINA_TRUE);
fail_if(tmp->i != 1664);
fail_if(eina_accessor_data_get(it, 3, (void **)&tmp) != EINA_TRUE);
fail_if(tmp->i != 1664);
fail_if(eina_accessor_data_get(it, 1, (void **)&tmp) != EINA_TRUE);
fail_if(tmp->i != 42);
eina_accessor_free(it);
fail_if(i != 2);
}
END_TEST
static Eina_Bool
eina_iterator_list_data_check(__UNUSED__ const Eina_List *list,
int *data,
int *fdata)
{
switch (*fdata)
{
case 0: fail_if(*data != 9); break;
case 1: fail_if(*data != 6); break;
}
(*fdata)++;
return EINA_TRUE;
}
START_TEST(eina_accessor_list_simple)
{
Eina_List *list = NULL;
Eina_Accessor *it;
int data[] = { 6, 9, 42, 1, 7, 1337, 81, 1664 };
int *j;
int i = 0;
eina_init();
list = eina_list_append(list, &data[0]);
fail_if(list == NULL);
list = eina_list_prepend(list, &data[1]);
fail_if(list == NULL);
list = eina_list_append(list, &data[2]);
fail_if(list == NULL);
list = eina_list_append(list, &data[3]);
fail_if(list == NULL);
list = eina_list_prepend(list, &data[4]);
fail_if(list == NULL);
list = eina_list_append(list, &data[5]);
fail_if(list == NULL);
list = eina_list_prepend(list, &data[6]);
fail_if(list == NULL);
it = eina_list_accessor_new(list);
fail_if(!it);
eina_accessor_over(it, EINA_EACH_CB(eina_iterator_list_data_check), 2, 4, &i);
fail_if(eina_accessor_data_get(it, 5, (void **)&j) != EINA_TRUE);
fail_if(*j != 1);
fail_if(eina_accessor_data_get(it, 3, (void **)&j) != EINA_TRUE);
fail_if(*j != 6);
fail_if(eina_accessor_data_get(it, 3, (void **)&j) != EINA_TRUE);
fail_if(*j != 6);
fail_if(eina_accessor_data_get(it, 1, (void **)&j) != EINA_TRUE);
fail_if(*j != 7);
fail_if(eina_accessor_data_get(it, 5, (void **)&j) != EINA_TRUE);
fail_if(*j != 1);
eina_accessor_free(it);
}
END_TEST
void
eina_test_accessor(TCase *tc)
{
tcase_add_test(tc, eina_accessor_array_simple);
tcase_add_test(tc, eina_accessor_inlist_simple);
tcase_add_test(tc, eina_accessor_list_simple);
}

View File

@ -0,0 +1,191 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(eina_array_simple)
{
Eina_Array *ea;
char *tmp;
Eina_Array_Iterator it;
unsigned int i;
eina_init();
ea = eina_array_new(11);
fail_if(!ea);
for (i = 0; i < 201; ++i)
{
tmp = malloc(sizeof(char) * 10);
fail_if(!tmp);
eina_convert_itoa(i, tmp);
eina_array_push(ea, tmp);
}
fail_if(eina_array_data_get(ea, 10) == NULL);
fail_if(atoi(eina_array_data_get(ea, 10)) != 10);
tmp = eina_array_pop(ea);
fail_if(tmp == NULL);
fail_if(atoi(tmp) != 200);
free(tmp);
EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
{
fail_if((unsigned int)atoi(tmp) != i);
free(tmp);
}
fail_if(i != 200);
eina_array_clean(ea);
eina_array_flush(ea);
eina_array_free(ea);
eina_shutdown();
}
END_TEST
START_TEST(eina_array_static)
{
Eina_Array sea;
char *tmp;
Eina_Array_Iterator it;
unsigned int i;
eina_init();
eina_array_step_set(&sea, sizeof(sea), 10);
for (i = 0; i < 200; ++i)
{
tmp = malloc(sizeof(char) * 10);
fail_if(!tmp);
eina_convert_itoa(i, tmp);
eina_array_push(&sea, tmp);
}
fail_if(eina_array_data_get(&sea, 10) == NULL);
fail_if(atoi(eina_array_data_get(&sea, 10)) != 10);
EINA_ARRAY_ITER_NEXT(&sea, i, tmp, it)
{
fail_if((unsigned int)atoi(tmp) != i);
free(tmp);
}
fail_if(i != 200);
eina_array_clean(&sea);
eina_array_flush(&sea);
eina_shutdown();
}
END_TEST
Eina_Bool
keep_int(void *data, void *gdata)
{
int *tmp = data;
fail_if(gdata);
fail_if(!tmp);
if (*tmp == 0)
return EINA_FALSE;
return EINA_TRUE;
}
START_TEST(eina_array_remove_stuff)
{
Eina_Array *ea;
int *tmp;
Eina_Array_Iterator it;
unsigned int i;
eina_init();
ea = eina_array_new(64);
fail_if(!ea);
for (i = 0; i < 1000; ++i)
{
tmp = malloc(sizeof(int));
fail_if(!tmp);
*tmp = i;
eina_array_push(ea, tmp);
}
// Remove the first 10 items
for (i = 0; i < 10; ++i)
{
tmp = eina_array_data_get(ea, i);
fail_if(!tmp);
*tmp = 0;
}
fail_if(eina_array_remove(ea, keep_int, NULL) != EINA_TRUE);
fail_if(eina_array_count_get(ea) != 990);
EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
fail_if(*tmp == 0);
// Remove the last items
for (i = 980; i < 990; ++i)
{
tmp = eina_array_data_get(ea, i);
fail_if(!tmp);
*tmp = 0;
}
eina_array_remove(ea, keep_int, NULL);
// Remove all items
fail_if(eina_array_count_get(ea) != 980);
EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
{
fail_if(*tmp == 0);
*tmp = 0;
}
eina_array_remove(ea, keep_int, NULL);
fail_if(eina_array_count_get(ea) != 0);
eina_array_free(ea);
eina_shutdown();
}
END_TEST
void
eina_test_array(TCase *tc)
{
tcase_add_test(tc, eina_array_simple);
tcase_add_test(tc, eina_array_static);
tcase_add_test(tc, eina_array_remove_stuff);
}

View File

@ -0,0 +1,76 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h>
#include "eina_suite.h"
#include "eina_benchmark.h"
static int global_test = 0;
static void
_eina_benchmark_specimens(int request)
{
int i;
int a = 0;
for (i = 0; i < request; ++i)
a += i;
global_test = a;
}
START_TEST(eina_benchmark_simple)
{
Eina_Benchmark *eb;
Eina_Array_Iterator it;
Eina_Array *ea;
char *tmp;
unsigned int i;
eb = eina_benchmark_new("benchmark", "test");
fail_if(!eb);
eina_benchmark_register(eb, "specimens_check",
EINA_BENCHMARK(_eina_benchmark_specimens),
1000, 1100, 100);
ea = eina_benchmark_run(eb);
fail_if(!ea);
EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
{
fail_if(!tmp);
fail_if(unlink(tmp));
}
fail_if(global_test != 499500);
eina_benchmark_free(eb);
}
END_TEST
void
eina_test_benchmark(TCase *tc)
{
tcase_add_test(tc, eina_benchmark_simple);
}

View File

@ -0,0 +1,199 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "eina_suite.h"
#include "Eina.h"
#define TEST0 "te\0st/0"
#define TEST0_SIZE 7
#define TEST1 "te\0st/11"
#define TEST1_SIZE 8
START_TEST(eina_binshare_simple)
{
const char *t0;
const char *t1;
eina_init();
t0 = eina_binshare_add_length(TEST0, TEST0_SIZE);
t1 = eina_binshare_add_length(TEST1, TEST1_SIZE);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(memcmp(t0, TEST0, TEST0_SIZE) != 0);
fail_if(memcmp(t1, TEST1, TEST1_SIZE) != 0);
t0 = eina_binshare_ref(t0);
fail_if(t0 == NULL);
fail_if(memcmp(t0, TEST0, TEST0_SIZE) != 0);
eina_binshare_del(t0);
eina_binshare_del(t0);
eina_binshare_del(t1);
eina_shutdown();
}
END_TEST
START_TEST(eina_binshare_small)
{
char buf[4];
int i;
eina_init();
for (i = 1; i < 3; i++)
{
const char *t0, *t1;
int j;
for (j = 0; j < i; j++)
{
char c;
for (c = 'a'; c <= 'z'; c++)
buf[j] = c;
}
buf[i] = '\0';
t0 = eina_binshare_add_length(buf, i);
t1 = eina_binshare_add_length(buf, i);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(t0 != t1);
fail_if(memcmp(t0, buf, i) != 0);
eina_binshare_del(t0);
eina_binshare_del(t1);
}
eina_shutdown();
}
END_TEST
START_TEST(eina_binshare_test_share)
{
const char *t0;
const char *t1;
eina_init();
t0 = eina_binshare_add_length(TEST0, TEST0_SIZE);
t1 = eina_binshare_add_length(TEST0, TEST0_SIZE);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(memcmp(t0, TEST0, TEST0_SIZE) != 0);
fail_if(memcmp(t1, TEST0, TEST0_SIZE) != 0);
fail_if(t0 != t1);
fail_if(TEST0_SIZE != eina_binshare_length(t0));
eina_binshare_del(t0);
eina_binshare_del(t1);
eina_shutdown();
}
END_TEST
START_TEST(eina_binshare_putstuff)
{
const char *tmp;
int i;
eina_init();
for (i = 10000; i > 0; --i)
{
char build[64] = "string_";
eina_convert_xtoa(i, build + 7);
tmp = eina_binshare_add_length(build, strlen(build));
fail_if(tmp != eina_binshare_add_length(build, strlen(build)));
fail_if((int)strlen(build) != eina_binshare_length(tmp));
}
eina_shutdown();
}
END_TEST
START_TEST(eina_binshare_collision)
{
Eina_Array *ea;
char buffer[50];
int i;
srand(time(NULL));
eina_init();
ea = eina_array_new(256);
fail_if(!ea);
for (i = 0; i < 10000; ++i)
{
eina_convert_itoa(rand(), buffer);
eina_array_push(ea,
(void *)eina_binshare_add_length(buffer, strlen(buffer)));
if (rand() > RAND_MAX / 2)
{
const char *r = eina_binshare_add_length(buffer, strlen(buffer));
fail_if(r == NULL);
}
}
for (i = 0; i < 10000; ++i)
{
const char *r;
eina_convert_itoa(60000 - i, buffer);
eina_array_push(ea,
(void *)eina_binshare_add_length(buffer, strlen(buffer)));
r = eina_binshare_add_length(buffer, strlen(buffer));
fail_if(r == NULL);
r = eina_binshare_add_length(buffer, strlen(buffer));
fail_if(r == NULL);
}
for (i = 0; i < 200; ++i)
eina_binshare_del(eina_array_data_get(ea, i));
for (i = 0; i < 1000; ++i)
eina_binshare_del(eina_array_pop(ea));
eina_shutdown();
eina_array_free(ea);
}
END_TEST
void
eina_test_binshare(TCase *tc)
{
tcase_add_test(tc, eina_binshare_simple);
tcase_add_test(tc, eina_binshare_small);
tcase_add_test(tc, eina_binshare_test_share);
tcase_add_test(tc, eina_binshare_collision);
tcase_add_test(tc, eina_binshare_putstuff);
}

View File

@ -0,0 +1,165 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <float.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(eina_convert_simple)
{
char tmp[128];
fail_if(eina_convert_itoa(0, tmp) != 1);
fail_if(strcmp(tmp, "0") != 0);
fail_if(eina_convert_itoa(-1, tmp) != 2);
fail_if(strcmp(tmp, "-1") != 0);
fail_if(eina_convert_itoa(100, tmp) != 3);
fail_if(strcmp(tmp, "100") != 0);
fail_if(eina_convert_itoa(-100, tmp) != 4);
fail_if(strcmp(tmp, "-100") != 0);
fail_if(eina_convert_itoa(10000000, tmp) != 8);
fail_if(strcmp(tmp, "10000000") != 0);
fail_if(eina_convert_xtoa(0, tmp) != 1);
fail_if(strcmp(tmp, "0") != 0);
fail_if(eina_convert_xtoa(0xA1, tmp) != 2);
fail_if(strcmp(tmp, "a1") != 0);
fail_if(eina_convert_xtoa(0xFF00EF0E, tmp) != 8);
fail_if(strcmp(tmp, "ff00ef0e") != 0);
}
END_TEST
#define EET_TEST_DOUBLE0 123.45689
#define EET_TEST_DOUBLE1 1.0
#define EET_TEST_DOUBLE2 0.25
#define EET_TEST_DOUBLE3 0.0001234
#define EET_TEST_DOUBLE4 123456789.9876543210
static void
_eina_convert_check(double test, int length)
{
char tmp[128];
long long int m = 0;
long e = 0;
double r;
fail_if(eina_convert_dtoa(test, tmp) != length);
fail_if(eina_convert_atod(tmp, 128, &m, &e) != EINA_TRUE);
r = ldexp((double)m, e);
fail_if(fabs(r - test) > DBL_MIN);
}
START_TEST(eina_convert_double)
{
long long int m = 0;
long e = 0;
eina_init();
_eina_convert_check(EET_TEST_DOUBLE0, 20);
_eina_convert_check(-EET_TEST_DOUBLE0, 21);
_eina_convert_check(EET_TEST_DOUBLE1, 6);
_eina_convert_check(EET_TEST_DOUBLE2, 6);
_eina_convert_check(EET_TEST_DOUBLE3, 21);
_eina_convert_check(EET_TEST_DOUBLE4, 21);
fail_if(eina_convert_atod("ah ah ah", 8, &m, &e) != EINA_FALSE);
fail_if(eina_convert_atod("0xjo", 8, &m, &e) != EINA_FALSE);
fail_if(eina_convert_atod("0xp", 8, &m, &e) != EINA_FALSE);
eina_shutdown();
}
END_TEST
static void
_eina_convert_fp_check(double d, Eina_F32p32 fp, int length)
{
char tmp1[128];
char tmp2[128];
Eina_F32p32 fpc;
double fpd;
int l1;
int l2;
l1 = eina_convert_dtoa(d, tmp1);
l2 = eina_convert_fptoa(fp, tmp2);
/* fprintf(stderr, "[%s](%i) vs [%s](%i)\n", tmp1, l1, tmp2, l2); */
fail_if(l1 != l2);
fail_if(length != l1);
fail_if(strcmp(tmp1, tmp2) != 0);
fail_if(!eina_convert_atofp(tmp2, l2, &fpc));
/* fprintf(stderr, "%016x vs %016x\n", fpc, fp); */
fail_if(fpc != fp);
fail_if(!eina_convert_atofp(tmp1, l1, &fpc));
fpd = eina_f32p32_double_to(fpc);
/* fprintf(stderr, "%0.16f vs %0.16f\n", fpd, d); */
fail_if(fabs(fpd - d) > DBL_MIN);
d = -d;
fp = -fp;
l1 = eina_convert_dtoa(d, tmp1);
l2 = eina_convert_fptoa(fp, tmp2);
fail_if(l1 != l2);
fail_if(length + 1 != l1);
fail_if(strcmp(tmp1, tmp2) != 0);
fail_if(!eina_convert_atofp(tmp2, l2, &fpc));
/* fprintf(stderr, "%016x vs %016x\n", fpc, fp); */
fail_if(fpc != fp);
fail_if(!eina_convert_atofp(tmp1, l1, &fpc));
fpd = eina_f32p32_double_to(fpc);
/* fprintf(stderr, "%0.16f vs %0.16f\n", fpd, d); */
fail_if(fabs(fpd - d) > DBL_MIN);
}
START_TEST(eina_convert_fp)
{
_eina_convert_fp_check(1.0, 0x0000000100000000, 6);
_eina_convert_fp_check(0.5, 0x0000000080000000, 8);
_eina_convert_fp_check(0.625, 0x00000000a0000000, 8);
_eina_convert_fp_check(256.0, 0x0000010000000000, 6);
_eina_convert_fp_check(0.5, 0x0000000080000000, 8);
_eina_convert_fp_check(128.625, 0x00000080a0000000, 10);
}
END_TEST
void
eina_test_convert(TCase *tc)
{
tcase_add_test(tc, eina_convert_simple);
tcase_add_test(tc, eina_convert_double);
tcase_add_test(tc, eina_convert_fp);
}

View File

@ -0,0 +1,108 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include "eina_suite.h"
#include "Eina.h"
#include "eina_safety_checks.h"
START_TEST(eina_counter_simple)
{
Eina_Counter *cnt;
char *dump;
int i;
eina_init();
cnt = eina_counter_new("eina_test");
fail_if(!cnt);
eina_counter_start(cnt);
for (i = 0; i < 100000; ++i)
{
void *tmp = malloc(sizeof(long int));
free(tmp);
}
eina_counter_stop(cnt, i);
eina_counter_start(cnt);
for (i = 0; i < 200000; ++i)
{
void *tmp = malloc(sizeof(long int));
free(tmp);
}
eina_counter_stop(cnt, i);
dump = eina_counter_dump(cnt);
fail_if(!dump);
fprintf(stderr, "%s", dump);
free(dump);
eina_counter_free(cnt);
eina_shutdown();
}
END_TEST
START_TEST(eina_counter_break)
{
Eina_Counter *cnt;
eina_init();
cnt = eina_counter_new("eina_test");
fail_if(!cnt);
eina_counter_stop(cnt, 10);
eina_counter_free(cnt);
#ifdef EINA_SAFETY_CHECKS
{
char *dump;
fprintf(stderr, "you should have a safety check failure below:\n");
dump = eina_counter_dump(NULL);
fail_if(dump);
fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
free(dump);
}
#endif
eina_shutdown();
}
END_TEST
void eina_test_counter(TCase *tc)
{
tcase_add_test(tc, eina_counter_simple);
tcase_add_test(tc, eina_counter_break);
}

View File

@ -0,0 +1,59 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_EVIL
# include <Evil.h>
#endif
#include "eina_suite.h"
#include "Eina.h"
#define TEST_TEXT "The big test\n"
START_TEST(eina_error_errno)
{
int test;
setenv("EINA_ERROR_LEVEL", "1", 0);
eina_init();
test = eina_error_msg_register(TEST_TEXT);
fail_if(!eina_error_msg_get(test));
fail_if(strcmp(eina_error_msg_get(test), TEST_TEXT) != 0);
eina_error_set(test);
fail_if(eina_error_get() != test);
eina_shutdown();
}
END_TEST
void
eina_test_error(TCase *tc)
{
tcase_add_test(tc, eina_error_errno);
}

View File

@ -0,0 +1,88 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "eina_suite.h"
#include "Eina.h"
#include "eina_safety_checks.h"
START_TEST(eina_file_split_simple)
{
Eina_Array *ea;
eina_init();
#ifdef EINA_SAFETY_CHECKS
fprintf(stderr, "you should have a safety check failure below:\n");
ea = eina_file_split(NULL);
fail_if(ea);
fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
#endif
#ifdef _WIN32
ea = eina_file_split(strdup("\\this\\is\\a\\small\\test"));
#else
ea = eina_file_split(strdup("/this/is/a/small/test"));
#endif
fail_if(!ea);
fail_if(eina_array_count_get(ea) != 5);
fail_if(strcmp(eina_array_data_get(ea, 0), "this"));
fail_if(strcmp(eina_array_data_get(ea, 1), "is"));
fail_if(strcmp(eina_array_data_get(ea, 2), "a"));
fail_if(strcmp(eina_array_data_get(ea, 3), "small"));
fail_if(strcmp(eina_array_data_get(ea, 4), "test"));
eina_array_free(ea);
#ifdef _WIN32
ea =
eina_file_split(strdup(
"this\\\\is\\\\\\a \\more\\complex\\\\\\case\\\\\\"));
#else
ea = eina_file_split(strdup("this//is///a /more/complex///case///"));
#endif
fail_if(!ea);
fail_if(eina_array_count_get(ea) != 6);
fail_if(strcmp(eina_array_data_get(ea, 0), "this"));
fail_if(strcmp(eina_array_data_get(ea, 1), "is"));
fail_if(strcmp(eina_array_data_get(ea, 2), "a "));
fail_if(strcmp(eina_array_data_get(ea, 3), "more"));
fail_if(strcmp(eina_array_data_get(ea, 4), "complex"));
fail_if(strcmp(eina_array_data_get(ea, 5), "case"));
eina_array_free(ea);
eina_shutdown();
}
END_TEST
void
eina_test_file(TCase *tc)
{
tcase_add_test(tc, eina_file_split_simple);
}

View File

@ -0,0 +1,93 @@
/* EINA - EFL data type library
* Copyright (C) 2010 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(eina_fp_cos)
{
Eina_F32p32 fc;
Eina_F32p32 fl;
Eina_F32p32 step;
Eina_F32p32 fresult;
double dc;
double dresult;
double delta;
fail_if(!eina_init());
fl = eina_f32p32_scale(EINA_F32P32_PI, 4);
step = eina_f32p32_div(fl, eina_f32p32_int_from(2048));
for (fc = 0; fc < fl; fc += step)
{
fresult = eina_f32p32_cos(fc);
dc = eina_f32p32_double_to(fc);
dresult = cos(dc);
delta = fabs(dresult - eina_f32p32_double_to(fresult));
fail_if(delta > 0.005);
}
eina_shutdown();
}
END_TEST
START_TEST(eina_fp_sin)
{
Eina_F32p32 fc;
Eina_F32p32 fl;
Eina_F32p32 step;
Eina_F32p32 fresult;
double dc;
double dresult;
double delta;
fail_if(!eina_init());
fl = eina_f32p32_scale(EINA_F32P32_PI, 4);
step = eina_f32p32_div(fl, eina_f32p32_int_from(2048));
for (fc = 0; fc < fl; fc += step)
{
fresult = eina_f32p32_sin(fc);
dc = eina_f32p32_double_to(fc);
dresult = sin(dc);
delta = fabs(dresult - eina_f32p32_double_to(fresult));
fail_if(delta > 0.005);
}
eina_shutdown();
}
END_TEST
void
eina_test_fp(TCase *tc)
{
tcase_add_test(tc, eina_fp_cos);
tcase_add_test(tc, eina_fp_sin);
}

View File

@ -0,0 +1,206 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "eina_suite.h"
#include "Eina.h"
static Eina_Bool
eina_foreach_check(__UNUSED__ const Eina_Hash *hash,
const void *key,
void *data,
__UNUSED__ void *fdata)
{
int *j = data;
int i;
if (strlen(key) <= 0)
return EINA_TRUE;
i = atoi(key);
fail_if(i != *j);
return EINA_TRUE;
}
START_TEST(eina_hash_simple)
{
Eina_Hash *hash = NULL;
int *test;
int array[] = { 1, 42, 4, 5, 6 };
/* As mempool is already initialized and it use hash, we should have 2 init. */
fail_if(eina_init() != 2);
hash = eina_hash_string_superfast_new(NULL);
fail_if(hash == NULL);
fail_if(eina_hash_add(hash, "1", &array[0]) != EINA_TRUE);
fail_if(eina_hash_add(hash, "42", &array[1]) != EINA_TRUE);
fail_if(eina_hash_direct_add(hash, "4", &array[2]) != EINA_TRUE);
fail_if(eina_hash_direct_add(hash, "5", &array[3]) != EINA_TRUE);
fail_if(eina_hash_add(hash, "", "") != EINA_TRUE);
test = eina_hash_find(hash, "4");
fail_if(!test);
fail_if(*test != 4);
test = eina_hash_find(hash, "42");
fail_if(!test);
fail_if(*test != 42);
eina_hash_foreach(hash, eina_foreach_check, NULL);
test = eina_hash_modify(hash, "5", &array[4]);
fail_if(!test);
fail_if(*test != 5);
test = eina_hash_find(hash, "5");
fail_if(!test);
fail_if(*test != 6);
fail_if(eina_hash_population(hash) != 5);
fail_if(eina_hash_find(hash, "120") != NULL);
fail_if(eina_hash_del(hash, "5", NULL) != EINA_TRUE);
fail_if(eina_hash_find(hash, "5") != NULL);
fail_if(eina_hash_del(hash, NULL, &array[2]) != EINA_TRUE);
fail_if(eina_hash_find(hash, "4") != NULL);
fail_if(eina_hash_del(hash, NULL, &array[2]) != EINA_FALSE);
fail_if(eina_hash_del(hash, "1", NULL) != EINA_TRUE);
fail_if(eina_hash_del(hash, "42", NULL) != EINA_TRUE);
eina_hash_free(hash);
/* Same comment as eina_init */
fail_if(eina_shutdown() != 1);
}
END_TEST
START_TEST(eina_hash_extended)
{
Eina_Hash *hash = NULL;
int i;
fail_if(eina_init() != 2);
hash = eina_hash_string_djb2_new(NULL);
fail_if(hash == NULL);
fail_if(eina_hash_direct_add(hash, "42", "42") != EINA_TRUE);
for (i = 43; i < 3043; ++i)
{
char *tmp = malloc(10);
fail_if(!tmp);
eina_convert_itoa(i, tmp);
fail_if(eina_hash_direct_add(hash, tmp, tmp) != EINA_TRUE);
}
fail_if(eina_hash_find(hash, "42") == NULL);
eina_hash_free(hash);
fail_if(eina_shutdown() != 1);
}
END_TEST
START_TEST(eina_hash_double_item)
{
Eina_Hash *hash = NULL;
int i[] = { 7, 7 };
int *test;
fail_if(eina_init() != 2);
hash = eina_hash_string_superfast_new(NULL);
fail_if(hash == NULL);
fail_if(eina_hash_add(hash, "7", &i[0]) != EINA_TRUE);
fail_if(eina_hash_add(hash, "7", &i[1]) != EINA_TRUE);
fail_if(eina_hash_del(hash, "7", &i[1]) != EINA_TRUE);
test = eina_hash_find(hash, "7");
fail_if(test != &i[0]);
eina_hash_free(hash);
fail_if(eina_shutdown() != 1);
}
END_TEST
START_TEST(eina_hash_all_int)
{
Eina_Hash *hash;
int64_t j[] = { 4321312301243122, 6, 7, 128 };
int i[] = { 42, 6, 7, 0 };
int64_t *test2;
int *test;
int it;
fail_if(eina_init() != 2);
hash = eina_hash_int32_new(NULL);
fail_if(hash == NULL);
for (it = 0; it < 4; ++it)
fail_if(eina_hash_add(hash, &i[it], &i[it]) != EINA_TRUE);
fail_if(eina_hash_del(hash, &i[1], &i[1]) != EINA_TRUE);
test = eina_hash_find(hash, &i[2]);
fail_if(test != &i[2]);
test = eina_hash_find(hash, &i[3]);
fail_if(test != &i[3]);
eina_hash_free(hash);
hash = eina_hash_int64_new(NULL);
fail_if(hash == NULL);
for (it = 0; it < 4; ++it)
fail_if(eina_hash_add(hash, &j[it], &j[it]) != EINA_TRUE);
fail_if(eina_hash_del(hash, &j[1], &j[1]) != EINA_TRUE);
test2 = eina_hash_find(hash, &j[0]);
fail_if(test2 != &j[0]);
eina_hash_free(hash);
fail_if(eina_shutdown() != 1);
}
END_TEST
void eina_test_hash(TCase *tc)
{
tcase_add_test(tc, eina_hash_simple);
tcase_add_test(tc, eina_hash_extended);
tcase_add_test(tc, eina_hash_double_item);
tcase_add_test(tc, eina_hash_all_int);
}

View File

@ -0,0 +1,142 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
#include "eina_safety_checks.h"
typedef struct _Eina_Test_Inlist Eina_Test_Inlist;
struct _Eina_Test_Inlist
{
int i;
EINA_INLIST;
};
static Eina_Test_Inlist *
_eina_test_inlist_build(int i)
{
Eina_Test_Inlist *tmp;
tmp = malloc(sizeof(Eina_Test_Inlist));
fail_if(!tmp);
tmp->i = i;
return tmp;
}
START_TEST(eina_inlist_simple)
{
Eina_Inlist *lst = NULL;
Eina_Test_Inlist *tmp;
Eina_Test_Inlist *prev;
int i = 0;
tmp = _eina_test_inlist_build(42);
lst = eina_inlist_append(lst, EINA_INLIST_GET(tmp));
fail_if(!lst);
lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
lst = eina_inlist_prepend(lst, EINA_INLIST_GET(tmp));
tmp = _eina_test_inlist_build(1664);
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst);
fail_if(!lst);
fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42);
prev = tmp;
tmp = _eina_test_inlist_build(3227);
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(
tmp), EINA_INLIST_GET(prev));
fail_if(!lst);
fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42);
lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst);
lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), lst);
tmp = _eina_test_inlist_build(27);
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), NULL);
tmp = _eina_test_inlist_build(81);
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), NULL);
EINA_INLIST_FOREACH(lst, tmp)
{
switch (i)
{
case 0: fail_if(tmp->i != 27); break;
case 1: fail_if(tmp->i != 3227); break;
case 2: fail_if(tmp->i != 42); break;
case 3: fail_if(tmp->i != 1664); break;
case 4: fail_if(tmp->i != 81); break;
}
++i;
}
#ifdef EINA_SAFETY_CHECKS
fprintf(stderr, "you should have a safety check failure below:\n");
{
Eina_Inlist *tmp2 = eina_inlist_remove(NULL, EINA_INLIST_GET(tmp));
fail_if(tmp2 != NULL);
fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
}
fprintf(stderr, "you should have a safety check failure below:\n");
lst = eina_inlist_remove(lst, NULL);
fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
#endif
tmp = EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist);
lst = eina_inlist_demote(lst, lst);
fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist) == tmp);
lst = eina_inlist_promote(lst, EINA_INLIST_GET(tmp));
fail_if(lst != EINA_INLIST_GET(tmp));
tmp = EINA_INLIST_CONTAINER_GET(eina_inlist_find(lst, EINA_INLIST_GET(
prev)), Eina_Test_Inlist);
lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
prev = (Eina_Test_Inlist *)eina_inlist_find(lst, EINA_INLIST_GET(tmp));
tmp = prev ? EINA_INLIST_CONTAINER_GET(prev, Eina_Test_Inlist) : NULL;
fail_if(tmp != NULL);
while (lst)
lst = eina_inlist_remove(lst, lst);
}
END_TEST
void
eina_test_inlist(TCase *tc)
{
tcase_add_test(tc, eina_inlist_simple);
}

View File

@ -0,0 +1,465 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
static Eina_Bool
eina_iterator_array_check(__UNUSED__ const Eina_Array *array,
int *data, int *fdata)
{
fail_if(*fdata > *data);
*fdata = *data;
return EINA_TRUE;
}
START_TEST(eina_iterator_array_simple)
{
Eina_Iterator *it;
Eina_Array *ea;
int *tmp;
int i;
eina_init();
ea = eina_array_new(11);
fail_if(!ea);
for (i = 0; i < 200; ++i)
{
tmp = malloc(sizeof(int));
fail_if(!tmp);
*tmp = i;
eina_array_push(ea, tmp);
}
it = eina_array_iterator_new(ea);
fail_if(!it);
i = -1;
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_array_check), &i);
fail_if(i != 199);
fail_if(eina_iterator_container_get(it) != ea);
fail_if(eina_iterator_next(it, (void **)&tmp) != EINA_FALSE);
eina_iterator_free(it);
eina_array_free(ea);
eina_shutdown();
}
END_TEST
static Eina_Bool
eina_iterator_hash_key_check(const Eina_Hash *hash,
const char *key,
__UNUSED__ void *fdata)
{
fail_if(eina_hash_find(hash, key) == NULL);
return EINA_TRUE;
}
static Eina_Bool
eina_iterator_hash_data_check(const Eina_Hash *hash,
int *data,
__UNUSED__ void *fdata)
{
char tmp[10];
snprintf(tmp, 10, "%i", *data);
fail_if(eina_hash_find(hash, tmp) != data);
return EINA_TRUE;
}
static Eina_Bool
eina_iterator_hash_tuple_check(__UNUSED__ const Eina_Hash *hash,
Eina_Hash_Tuple *tuple,
__UNUSED__ void *fdata)
{
fail_if(atoi((char *)tuple->key) != *((int *)tuple->data));
return EINA_TRUE;
}
START_TEST(eina_iterator_hash_simple)
{
Eina_Iterator *it;
Eina_Hash *hash;
int array[] = { 1, 42, 7, 8, 6 };
eina_init();
hash = eina_hash_string_superfast_new(NULL);
fail_if(hash == NULL);
fail_if(eina_hash_add(hash, "1", &array[0]) != EINA_TRUE);
fail_if(eina_hash_add(hash, "42", &array[1]) != EINA_TRUE);
fail_if(eina_hash_add(hash, "7", &array[2]) != EINA_TRUE);
fail_if(eina_hash_add(hash, "8", &array[3]) != EINA_TRUE);
fail_if(eina_hash_add(hash, "6", &array[4]) != EINA_TRUE);
it = eina_hash_iterator_key_new(hash);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_hash_key_check), NULL);
eina_iterator_free(it);
it = eina_hash_iterator_data_new(hash);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_hash_data_check), NULL);
eina_iterator_free(it);
it = eina_hash_iterator_tuple_new(hash);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_hash_tuple_check), NULL);
eina_iterator_free(it);
eina_hash_free(hash);
eina_shutdown();
}
END_TEST
typedef struct _Eina_Test_Inlist Eina_Test_Inlist;
struct _Eina_Test_Inlist
{
EINA_INLIST;
int i;
};
static Eina_Test_Inlist *
_eina_test_inlist_build(int i)
{
Eina_Test_Inlist *tmp;
tmp = malloc(sizeof(Eina_Test_Inlist));
fail_if(!tmp);
tmp->i = i;
return tmp;
}
static Eina_Bool
eina_iterator_inlist_data_check(__UNUSED__ const Eina_Inlist *in_list,
Eina_Test_Inlist *data,
int *fdata)
{
switch (*fdata)
{
case 0: fail_if(data->i != 27); break;
case 1: fail_if(data->i != 42); break;
case 2: fail_if(data->i != 3227); break;
case 3: fail_if(data->i != 1664); break;
case 4: fail_if(data->i != 81); break;
}
(*fdata)++;
return EINA_TRUE;
}
START_TEST(eina_iterator_inlist_simple)
{
Eina_Inlist *lst = NULL;
Eina_Test_Inlist *tmp;
Eina_Test_Inlist *prev;
Eina_Iterator *it;
int i = 0;
tmp = _eina_test_inlist_build(42);
lst = eina_inlist_append(lst, EINA_INLIST_GET(tmp));
fail_if(!lst);
tmp = _eina_test_inlist_build(1664);
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst);
fail_if(!lst);
fail_if(((Eina_Test_Inlist *)lst)->i != 42);
prev = tmp;
tmp = _eina_test_inlist_build(3227);
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(
tmp), EINA_INLIST_GET(prev));
fail_if(!lst);
fail_if(((Eina_Test_Inlist *)lst)->i != 42);
tmp = _eina_test_inlist_build(27);
lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), NULL);
tmp = _eina_test_inlist_build(81);
lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), NULL);
it = eina_inlist_iterator_new(lst);
fail_if(!it);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_inlist_data_check), &i);
eina_iterator_free(it);
fail_if(i != 5);
}
END_TEST
static Eina_Bool
eina_iterator_list_data_check(__UNUSED__ const Eina_List *list,
int *data,
int *fdata)
{
switch (*fdata)
{
case 0: fail_if(*data != 81); break;
case 1: fail_if(*data != 7); break;
case 2: fail_if(*data != 9); break;
case 3: fail_if(*data != 6); break;
case 4: fail_if(*data != 42); break;
case 5: fail_if(*data != 1); break;
case 6: fail_if(*data != 1337); break;
}
(*fdata)++;
return EINA_TRUE;
}
START_TEST(eina_iterator_list_simple)
{
Eina_List *list = NULL;
Eina_Iterator *it;
int data[] = { 6, 9, 42, 1, 7, 1337, 81, 1664 };
int i = 0;
eina_init();
list = eina_list_append(list, &data[0]);
fail_if(list == NULL);
list = eina_list_prepend(list, &data[1]);
fail_if(list == NULL);
list = eina_list_append(list, &data[2]);
fail_if(list == NULL);
list = eina_list_append(list, &data[3]);
fail_if(list == NULL);
list = eina_list_prepend(list, &data[4]);
fail_if(list == NULL);
list = eina_list_append(list, &data[5]);
fail_if(list == NULL);
list = eina_list_prepend(list, &data[6]);
fail_if(list == NULL);
it = eina_list_iterator_new(list);
fail_if(!it);
eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_list_data_check), &i);
eina_iterator_free(it);
}
END_TEST
typedef struct _Eina_Rbtree_Int Eina_Rbtree_Int;
struct _Eina_Rbtree_Int
{
Eina_Rbtree node;
int value;
};
static Eina_Rbtree_Direction
eina_rbtree_int_cmp(const Eina_Rbtree_Int *left, const Eina_Rbtree_Int *right)
{
fail_if(!left);
fail_if(!right);
if (left->value < right->value)
return EINA_RBTREE_LEFT;
return EINA_RBTREE_RIGHT;
}
static Eina_Rbtree *
_eina_rbtree_int_new(int value)
{
Eina_Rbtree_Int *it;
it = malloc(sizeof (Eina_Rbtree_Int));
fail_if(!it);
it->value = value;
return &it->node;
}
static Eina_Bool
eina_iterator_rbtree_data_check_sorted(__UNUSED__ const Eina_List *list,
Eina_Rbtree_Int *data,
int *fdata)
{
switch (*fdata)
{
case 0: fail_if(data->value != 10); break;
case 1: fail_if(data->value != 27); break;
case 2: fail_if(data->value != 42); break;
case 3: fail_if(data->value != 69); break;
case 4: fail_if(data->value != 1337); break;
}
(*fdata)++;
return EINA_TRUE;
}
static Eina_Bool
eina_iterator_rbtree_data_check_prefix(__UNUSED__ const Eina_List *list,
Eina_Rbtree_Int *data,
int *fdata)
{
switch (*fdata)
{
case 0: fail_if(data->value != 27); break;
case 1: fail_if(data->value != 10); break;
case 2: fail_if(data->value != 69); break;
case 3: fail_if(data->value != 42); break;
case 4: fail_if(data->value != 1337); break;
}
(*fdata)++;
return EINA_TRUE;
}
static Eina_Bool
eina_iterator_rbtree_data_check_postfix(__UNUSED__ const Eina_List *list,
Eina_Rbtree_Int *data,
int *fdata)
{
switch (*fdata)
{
case 0: fail_if(data->value != 10); break;
case 1: fail_if(data->value != 42); break;
case 2: fail_if(data->value != 1337); break;
case 3: fail_if(data->value != 69); break;
case 4: fail_if(data->value != 27); break;
}
(*fdata)++;
return EINA_TRUE;
}
START_TEST(eina_iterator_rbtree_simple)
{
Eina_Rbtree *root = NULL;
Eina_Iterator *it;
int i;
root = eina_rbtree_inline_insert(NULL,
_eina_rbtree_int_new(10),
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp),
NULL);
fail_if(!root);
root = eina_rbtree_inline_insert(root,
_eina_rbtree_int_new(1337),
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp),
NULL);
fail_if(!root);
root = eina_rbtree_inline_insert(root,
_eina_rbtree_int_new(27),
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp),
NULL);
fail_if(!root);
root = eina_rbtree_inline_insert(root,
_eina_rbtree_int_new(69),
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp),
NULL);
fail_if(!root);
root = eina_rbtree_inline_insert(root,
_eina_rbtree_int_new(42),
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp),
NULL);
fail_if(!root);
i = 0;
it = eina_rbtree_iterator_prefix(root);
fail_if(!it);
eina_iterator_foreach(it,
EINA_EACH_CB(eina_iterator_rbtree_data_check_prefix),
&i);
eina_iterator_free(it);
/* This will return the item sorted. */
i = 0;
it = eina_rbtree_iterator_infix(root);
fail_if(!it);
eina_iterator_foreach(it,
EINA_EACH_CB(eina_iterator_rbtree_data_check_sorted),
&i);
eina_iterator_free(it);
i = 0;
it = eina_rbtree_iterator_postfix(root);
fail_if(!it);
eina_iterator_foreach(it,
EINA_EACH_CB(eina_iterator_rbtree_data_check_postfix),
&i);
eina_iterator_free(it);
}
END_TEST
void
eina_test_iterator(TCase *tc)
{
tcase_add_test(tc, eina_iterator_array_simple);
tcase_add_test(tc, eina_iterator_hash_simple);
tcase_add_test(tc, eina_iterator_inlist_simple);
tcase_add_test(tc, eina_iterator_list_simple);
tcase_add_test(tc, eina_iterator_rbtree_simple);
}

View File

@ -0,0 +1,89 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
typedef struct _Eina_Lazy_Allocator_Test Eina_Lazy_Allocator_Test;
struct _Eina_Lazy_Allocator_Test
{
void *data;
int num;
};
static Eina_Bool
_test_alloc(Eina_Lazy_Allocator_Test *elat, int num)
{
if (elat->num == 10 && num == 1)
return EINA_FALSE;
if (elat->num == 122 && num == 128)
return EINA_FALSE;
elat->num += num;
elat->data = realloc(elat->data, elat->num);
return EINA_TRUE;
}
static void
_test_free(Eina_Lazy_Allocator_Test *elat)
{
free(elat->data);
elat->data = NULL;
elat->num = 0;
}
START_TEST(eina_lalloc_simple)
{
Eina_Lazy_Allocator_Test *elat;
Eina_Lalloc *test;
int i;
elat = calloc(1, sizeof (Eina_Lazy_Allocator_Test));
fail_if(!elat);
test = eina_lalloc_new(elat, EINA_LALLOC_ALLOC(
_test_alloc), EINA_LALLOC_FREE(_test_free), 10);
fail_if(!test);
for (i = 0; i < 10; ++i)
fail_if(eina_lalloc_element_add(test) != EINA_TRUE);
fail_if(eina_lalloc_element_add(test) != EINA_FALSE);
fail_if(eina_lalloc_elements_add(test, 5) != EINA_TRUE);
for (i = 0; i < 21; ++i)
fail_if(eina_lalloc_element_add(test) != EINA_TRUE);
fail_if(eina_lalloc_elements_add(test, 50) != EINA_FALSE);
eina_lalloc_free(test);
}
END_TEST
void
eina_test_lalloc(TCase *tc)
{
tcase_add_test(tc, eina_lalloc_simple);
}

View File

@ -0,0 +1,347 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
static Eina_Bool eina_list_sorted_check(const Eina_List *list)
{
const Eina_List *n;
void *d;
int last = *(int *)list->data;
EINA_LIST_FOREACH(list->next, n, d)
{
int current = *(int *)d;
if (last > current)
{
fprintf(stderr, "list is not sorted: last=%d, current=%d\n",
last, current);
return 0;
}
last = current;
}
return 1;
}
static int eina_int_cmp(const void *a, const void *b)
{
const int *ia = a;
const int *ib = b;
return *ia - *ib;
}
START_TEST(eina_test_simple)
{
Eina_List *list = NULL;
Eina_List *tmp;
int *test1;
int *test2;
int *test3;
int data[] = { 6, 9, 42, 1, 7, 9, 81, 1664, 1337 };
int result[] = { 81, 9, 9, 7, 1 };
int i;
eina_init();
list = eina_list_append(list, &data[0]);
fail_if(list == NULL);
list = eina_list_prepend(list, &data[1]);
fail_if(list == NULL);
list = eina_list_append(list, &data[2]);
fail_if(list == NULL);
list = eina_list_remove(list, &data[0]);
fail_if(list == NULL);
list = eina_list_remove(list, &data[0]);
fail_if(list == NULL);
tmp = eina_list_data_find_list(list, &data[2]);
fail_if(tmp == NULL);
list = eina_list_append_relative_list(list, &data[3], tmp);
fail_if(list == NULL);
list = eina_list_prepend_relative_list(list, &data[4], tmp);
fail_if(list == NULL);
list = eina_list_promote_list(list, tmp);
fail_if(list == NULL);
list = eina_list_append_relative(list, &data[5], &data[2]);
fail_if(list == NULL);
list = eina_list_prepend_relative(list, &data[6], &data[2]);
fail_if(list == NULL);
list = eina_list_remove_list(list, tmp);
fail_if(list == NULL);
fail_if(eina_list_data_find_list(list, &data[2]) != NULL);
fail_if(eina_list_data_find(list, &data[2]) != NULL);
fail_if(eina_list_data_find(list, &data[5]) != &data[5]);
fail_if(eina_list_count(list) != 5);
fail_if(eina_list_nth(list, 4) != &data[3]);
fail_if(eina_list_nth(list, 10) != NULL);
fail_if(eina_list_nth_list(list, 10) != NULL);
for (tmp = list, i = 0; tmp != NULL; tmp = eina_list_next(tmp), ++i)
{
int *d = eina_list_data_get(tmp);
fail_if(d == NULL);
fail_if(*d != result[i]);
}
list = eina_list_reverse(list);
for (tmp = list; tmp != NULL; tmp = eina_list_next(tmp), --i)
{
int *d = eina_list_data_get(tmp);
fail_if(d == NULL);
fail_if(*d != result[i - 1]);
}
list = eina_list_append_relative(list, &data[7], &data[7]);
fail_if(list == NULL);
list = eina_list_prepend_relative(list, &data[8], &data[8]);
fail_if(list == NULL);
list = eina_list_sort(list, 2, eina_int_cmp);
list = eina_list_sort(list, 2, eina_int_cmp);
test1 = eina_list_nth(list, 0);
test2 = eina_list_nth(list, 1);
test3 = eina_list_nth(list, 2);
fail_if(test1 == NULL || test2 == NULL || test3 == NULL);
fail_if(*test1 > *test2);
fail_if(*test3 == *test2);
list = eina_list_sort(list, 5, eina_int_cmp);
test1 = eina_list_nth(list, 3);
test2 = eina_list_nth(list, 4);
test3 = eina_list_nth(list, 5);
fail_if(test1 == NULL || test2 == NULL || test3 == NULL);
fail_if(*test1 > *test2);
fail_if(*test3 > *test2);
list = eina_list_append(list, &data[8]);
fail_if(list == NULL);
list = eina_list_append(list, &data[7]);
fail_if(list == NULL);
list = eina_list_sort(list, -1, eina_int_cmp);
test1 = eina_list_nth(list, 0);
for (tmp = list; tmp != NULL; tmp = eina_list_next(tmp))
{
int *d = eina_list_data_get(tmp);
fail_if(*test1 > *d);
test1 = d;
}
test3 = eina_list_nth(list, 5);
fail_if(test3 == NULL);
list = eina_list_promote_list(list, list);
fail_if(list == NULL);
list = eina_list_promote_list(list, eina_list_last(list));
fail_if(list == NULL);
test1 = eina_list_nth(list, 0);
test2 = eina_list_nth(list, 1);
list = eina_list_promote_list(eina_list_next(list), list);
fail_if(list == NULL);
fail_if(eina_list_data_get(list) != test1);
fail_if(eina_list_data_get(eina_list_next(list)) != test2);
list = eina_list_remove_list(list, list);
fail_if(list == NULL);
list = eina_list_remove_list(list, eina_list_last(list));
fail_if(list == NULL);
list = eina_list_free(list);
fail_if(list != NULL);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_merge)
{
Eina_List *l1;
Eina_List *l2;
Eina_List *l3;
Eina_List *l4;
Eina_List *l5;
int data[] = { 6, 9, 42, 1, 7, 9, 81, 1664, 1337, 3, 21, 10, 0, 5, 2008 };
int i;
eina_init();
l1 = eina_list_append(NULL, &data[0]);
l1 = eina_list_append(l1, &data[1]);
l1 = eina_list_append(l1, &data[2]);
l1 = eina_list_append(l1, &data[3]);
fail_if(l1 == NULL);
l2 = eina_list_append(NULL, &data[4]);
l2 = eina_list_append(l2, &data[5]);
fail_if(l2 == NULL);
l1 = eina_list_merge(l1, l2);
fail_if(l1 == NULL);
fail_if(eina_list_count(l1) != 6);
for (i = 0, l2 = l1; ((l2 != NULL) && (i < 6)); ++i, l2 = l2->next)
fail_if(l2->data != &data[i]);
fail_if(i != 6);
fail_if(l2 != NULL);
eina_list_free(l1);
l1 = eina_list_append(NULL, &data[0]);
l1 = eina_list_append(l1, &data[1]);
fail_if(l1 == NULL);
l2 = eina_list_append(NULL, &data[2]);
l2 = eina_list_append(l2, &data[3]);
l2 = eina_list_append(l2, &data[4]);
l2 = eina_list_append(l2, &data[5]);
fail_if(l2 == NULL);
l1 = eina_list_merge(l1, l2);
fail_if(l1 == NULL);
fail_if(eina_list_count(l1) != 6);
for (i = 0, l2 = l1; ((l2 != NULL) && (i < 6)); ++i, l2 = l2->next)
fail_if(l2->data != &data[i]);
fail_if(i != 6);
fail_if(l2 != NULL);
l3 = eina_list_append(NULL, &data[6]);
l3 = eina_list_append(l3, &data[7]);
l3 = eina_list_append(l3, &data[8]);
l4 = eina_list_append(NULL, &data[9]);
l4 = eina_list_append(l4, &data[10]);
l4 = eina_list_append(l4, &data[11]);
l5 = eina_list_append(NULL, &data[12]);
l5 = eina_list_append(l5, &data[13]);
l5 = eina_list_append(l5, &data[14]);
l1 = eina_list_sort(l1, -1, eina_int_cmp);
l3 = eina_list_sort(l3, -1, eina_int_cmp);
l4 = eina_list_sort(l4, -1, eina_int_cmp);
l5 = eina_list_sort(l5, -1, eina_int_cmp);
l1 = eina_list_sorted_merge(l1, l3, eina_int_cmp);
fail_if(l1 == NULL);
fail_if(eina_list_count(l1) != 9);
l1 = eina_list_sorted_merge(l1, l4, eina_int_cmp);
fail_if(l1 == NULL);
fail_if(eina_list_count(l1) != 12);
l1 = eina_list_sorted_merge(l1, l5, eina_int_cmp);
fail_if(l1 == NULL);
fail_if(eina_list_count(l1) != 15);
fail_if(!eina_list_sorted_check(l1));
eina_shutdown();
}
END_TEST
START_TEST(eina_test_sorted_insert)
{
const int data[] = {6, 9, 42, 1, 7, 9, 81, 1664, 1337, 3, 21, 10, 0, 5, 2008};
const int data2[] = {5, 0, 3, 2, 1, 0, 1, 2, 3, 4, 5};
int i, count;
Eina_List *l1, *l2, *itr;
void *d;
eina_init();
count = sizeof(data) / sizeof(data[0]);
l1 = NULL;
for (i = 0; i < count; i++)
l1 = eina_list_sorted_insert(l1, eina_int_cmp, data + i);
fail_if(l1 == NULL);
fail_if(!eina_list_sorted_check(l1));
l2 = NULL;
EINA_LIST_FOREACH(l1, itr, d)
l2 = eina_list_sorted_insert(l2, eina_int_cmp, d);
fail_if(l2 == NULL);
fail_if(!eina_list_sorted_check(l2));
eina_list_free(l2);
l2 = NULL;
EINA_LIST_REVERSE_FOREACH(l1, itr, d)
l2 = eina_list_sorted_insert(l2, eina_int_cmp, d);
fail_if(l2 == NULL);
fail_if(!eina_list_sorted_check(l2));
eina_list_free(l2);
eina_list_free(l1);
count = sizeof(data2) / sizeof(data2[0]);
l1 = NULL;
for (i = 0; i < count; i++)
l1 = eina_list_sorted_insert(l1, eina_int_cmp, data2 + i);
fail_if(l1 == NULL);
fail_if(!eina_list_sorted_check(l1));
eina_list_free(l1);
eina_shutdown();
}
END_TEST
void
eina_test_list(TCase *tc)
{
tcase_add_test(tc, eina_test_simple);
tcase_add_test(tc, eina_test_merge);
tcase_add_test(tc, eina_test_sorted_insert);
}

View File

@ -0,0 +1,235 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(eina_log_macro)
{
fail_if(!eina_init());
eina_log_level_set(EINA_LOG_LEVEL_DBG);
eina_log_print_cb_set(eina_log_print_cb_file, stderr);
EINA_LOG_CRIT("Critical message\n");
EINA_LOG_ERR("An error\n");
EINA_LOG_INFO("An info\n");
EINA_LOG_WARN("A warning\n");
EINA_LOG_DBG("A debug\n");
eina_shutdown();
}
END_TEST
START_TEST(eina_log_domains_macros)
{
fail_if(!eina_init());
int d = eina_log_domain_register("MyDomain", EINA_COLOR_GREEN);
fail_if(d < 0);
EINA_LOG_DOM_CRIT(d, "A critical message\n");
EINA_LOG_DOM_ERR(d, "An error\n");
EINA_LOG_DOM_WARN(d, "A warning\n");
EINA_LOG_DOM_DBG(d, "A debug\n");
EINA_LOG_DOM_INFO(d, "An info\n");
eina_shutdown();
}
END_TEST
START_TEST(eina_log_domains_registry)
{
fail_if(!eina_init());
int i;
int d[50];
for (i = 0; i < 50; i++)
{
d[i] = eina_log_domain_register("Test", EINA_COLOR_GREEN);
fail_if(d[i] < 0);
}
for (i = 0; i < 50; i++)
eina_log_domain_unregister(d[i]);
eina_shutdown();
}
END_TEST
START_TEST(eina_log_domains_slot_reuse)
{
fail_if(!eina_init());
fail_if(!eina_threads_init());
// Create 9 domains
int idx[9];
int i;
for (i = 0; i < 9; i++)
{
idx[i] = eina_log_domain_register("Test1", EINA_COLOR_GREEN);
fail_if(idx[i] < 0);
}
// Slot 0 by default contains the global logger. The above code created
// domains for slots indexes from 1 to 9.
//
// The global logger allocated the first 8 initial slots. The 8th domain
// registered on the for loop will create 8 more slots.
//
// Test will just unregister a domain between 1 and 9 and assure that a new
// domain register will be placed on the available slot and not at the end.
int removed = idx[5];
eina_log_domain_unregister(removed);
int new = eina_log_domain_register("Test Slot", EINA_COLOR_GREEN);
// Check for slot reuse
fail_if(new != removed);
eina_threads_shutdown();
eina_shutdown();
}
END_TEST
START_TEST(eina_log_level_indexes)
{
fail_if(!eina_init());
fail_if(!eina_threads_init());
fail_if(!eina_threads_init());
int d = eina_log_domain_register("Levels", EINA_COLOR_GREEN);
fail_if(d < 0);
// Displayed unless user sets level lower than -1
EINA_LOG(d, -1, "Negative index message\n");
// Displayed only if user sets level 6 or higher
EINA_LOG(d, 6, "Higher level debug\n");
eina_threads_shutdown();
eina_threads_shutdown();
eina_shutdown();
}
END_TEST
START_TEST(eina_log_customize)
{
int d;
/* please don't define EINA_LOG_LEVELS for it */
#define TEST_DOM "_Test_Log_Dom"
fail_if(!eina_init());
#define test_set_get(func, val) \
eina_log_ ## func ## _set(val); \
fail_if(eina_log_ ## func ## _get() != val)
test_set_get(level, -1234);
test_set_get(level, 4567);
#define test_set_get_bool(func) \
test_set_get(func, EINA_FALSE); \
test_set_get(func, EINA_TRUE)
test_set_get_bool(color_disable);
test_set_get_bool(file_disable);
test_set_get_bool(function_disable);
test_set_get_bool(abort_on_critical);
test_set_get(abort_on_critical_level, -1234);
test_set_get(abort_on_critical_level, 4567);
fail_if(eina_log_domain_level_get(TEST_DOM) != eina_log_level_get());
eina_log_domain_level_set(TEST_DOM, -123);
fail_if(eina_log_domain_level_get(TEST_DOM) != -123);
eina_log_domain_level_set(TEST_DOM, 890);
fail_if(eina_log_domain_level_get(TEST_DOM) != 890);
d = eina_log_domain_register(TEST_DOM, EINA_COLOR_GREEN);
fail_if(d < 0);
fail_if(eina_log_domain_level_get(TEST_DOM) != 890);
fail_if(eina_log_domain_registered_level_get(d) != 890);
eina_log_domain_unregister(d);
fputs("NOTE: You should see a failed safety check or "
"a crash if compiled without safety checks support.\n",
stderr);
eina_log_abort_on_critical_set(EINA_FALSE);
fail_if(eina_log_domain_registered_level_get(d) != EINA_LOG_LEVEL_UNKNOWN);
#undef test_set_get_bool
#undef test_set_get
eina_shutdown();
}
END_TEST
START_TEST(eina_log_level_name)
{
char name[4];
fail_if(!eina_init());
#define tst(level, str) \
eina_log_level_name_get(level, name); \
fail_if(strcmp(name, str) != 0)
tst(0, "CRI");
tst(1, "ERR");
tst(2, "WRN");
tst(3, "INF");
tst(4, "DBG");
tst(5, "005");
tst(12, "012");
tst(369, "369");
tst(-1, "-01");
tst(-48, "-48");
#undef tst
eina_shutdown();
}
END_TEST
void
eina_test_log(TCase *tc)
{
tcase_add_test(tc, eina_log_macro);
tcase_add_test(tc, eina_log_domains_macros);
tcase_add_test(tc, eina_log_domains_registry);
tcase_add_test(tc, eina_log_domains_slot_reuse);
tcase_add_test(tc, eina_log_level_indexes);
tcase_add_test(tc, eina_log_customize);
tcase_add_test(tc, eina_log_level_name);
}

View File

@ -0,0 +1,96 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define EINA_MAGIC_DEBUG
#include "eina_suite.h"
#include "Eina.h"
#include "eina_safety_checks.h"
#define EINA_MAGIC_TEST 0x7781fee7
#define EINA_MAGIC_TEST2 0x42241664
#define EINA_MAGIC_STRING "Eina Magic Test"
typedef struct _Eina_Magic_Struct Eina_Magic_Struct;
struct _Eina_Magic_Struct
{
EINA_MAGIC
};
START_TEST(eina_magic_simple)
{
Eina_Magic_Struct *ems = NULL;
eina_init();
eina_magic_string_set(EINA_MAGIC_TEST, EINA_MAGIC_STRING);
#ifdef EINA_SAFETY_CHECKS
fprintf(stderr, "you should have a safety check failure below:\n");
eina_magic_string_set(EINA_MAGIC_TEST2, NULL);
fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
fprintf(stderr, "you should have a safety check failure below:\n");
eina_magic_string_set(EINA_MAGIC_TEST2, NULL);
fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
#endif
eina_magic_string_set(EINA_MAGIC_TEST2, EINA_MAGIC_STRING);
fail_if(eina_magic_string_get(EINA_MAGIC_TEST) == NULL);
fail_if(strcmp(eina_magic_string_get(
EINA_MAGIC_TEST), EINA_MAGIC_STRING) != 0);
#ifdef EINA_MAGIC_DEBUG
fail_if(EINA_MAGIC_CHECK(ems, EINA_MAGIC_TEST));
fprintf(stderr, "you should see 'Input handle pointer is NULL' below\n");
EINA_MAGIC_FAIL(ems, EINA_MAGIC_TEST);
ems = malloc(sizeof (Eina_Magic_Struct));
fail_if(!ems);
EINA_MAGIC_SET(ems, EINA_MAGIC_TEST);
fail_if(!EINA_MAGIC_CHECK(ems, EINA_MAGIC_TEST));
EINA_MAGIC_SET(ems, EINA_MAGIC_NONE);
fprintf(stderr,
"you should see 'Input handle has already been freed' below\n");
EINA_MAGIC_FAIL(ems, EINA_MAGIC_TEST);
EINA_MAGIC_SET(ems, 42424242);
fprintf(stderr, "you should see 'Input handle is wrong type' below\n");
EINA_MAGIC_FAIL(ems, EINA_MAGIC_TEST);
#endif
eina_shutdown();
}
END_TEST
void eina_test_magic(TCase *tc)
{
tcase_add_test(tc, eina_magic_simple);
}

View File

@ -0,0 +1,62 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(eina_simple)
{
fail_if(eina_init() != 2); /* one init by test suite */
fail_if(eina_shutdown() != 1);
}
END_TEST
START_TEST(eina_cpu)
{
fail_if(eina_init() != 2); /* one init by test suite */
fail_if(eina_cpu_count() <= 0);
eina_cpu_features_get();
fail_if(eina_shutdown() != 1);
}
END_TEST
START_TEST(eina_hamster)
{
fail_if(eina_init() != 2); /* one init by test suite */
fail_if(eina_hamster_count() <= 0);
fail_if(eina_shutdown() != 1);
}
END_TEST
void eina_test_main(TCase *tc)
{
tcase_add_test(tc, eina_simple);
tcase_add_test(tc, eina_cpu);
tcase_add_test(tc, eina_hamster);
}

View File

@ -0,0 +1,489 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
#define MAX_ROWS 10
#define MAX_COLS 10
static void eina_matrixsparse_free_cell_cb(void *user_data __UNUSED__,
void *cell_data __UNUSED__)
{
}
static void matrixsparse_initialize(Eina_Matrixsparse *matrix,
long data[MAX_ROWS][MAX_COLS],
unsigned long nrows,
unsigned long ncols)
{
unsigned long i, j;
Eina_Bool r;
for (i = 0; i < nrows; i++)
for (j = 0; j < ncols; j++)
if (data[i][j] != 0)
{
r = eina_matrixsparse_data_idx_set(matrix, i, j, &data[i][j]);
fail_if(r == EINA_FALSE);
}
}
static void matrixsparse_check(Eina_Matrixsparse *matrix,
long data[MAX_ROWS][MAX_COLS],
unsigned long nrows __UNUSED__,
unsigned long ncols __UNUSED__)
{
unsigned long i, j;
long *test1;
for (i = 0; i < MAX_ROWS; i++)
for (j = 0; j < MAX_COLS; j++)
{
if (data[i][j] != 0)
{
test1 = eina_matrixsparse_data_idx_get(matrix, i, j);
fail_if(test1 == NULL || *test1 != data[i][j]);
}
else
{
test1 = eina_matrixsparse_data_idx_get(matrix, i, j);
fail_if(test1 != NULL);
}
}
}
START_TEST(eina_test_simple)
{
Eina_Matrixsparse *matrix = NULL;
Eina_Matrixsparse_Cell *cell = NULL;
Eina_Bool r;
long *test1, value, value2, value3, value4;
unsigned long i, j;
unsigned long row, col;
long data[MAX_ROWS][MAX_COLS];
for (i = 0; i < MAX_ROWS; i++)
for (j = 0; j < MAX_COLS; j++)
data[i][j] = 0;
data[0][3] = 3;
data[1][3] = 13;
data[1][6] = 16;
data[1][9] = 19;
data[1][8] = 18;
data[1][7] = 17;
data[2][8] = 28;
data[2][7] = 27;
data[2][6] = 26;
data[3][5] = 35;
data[3][6] = 36;
data[3][7] = 37;
data[3][9] = 39;
data[3][0] = 30;
data[4][6] = 46;
data[4][8] = 48;
data[4][2] = 42;
data[4][3] = 43;
data[4][7] = 47;
data[5][3] = 53;
data[6][3] = 63;
data[6][4] = 64;
data[6][6] = 66;
data[7][3] = 73;
data[7][7] = 77;
data[8][8] = 88;
value = -1;
value2 = -2;
value3 = -3;
value4 = -4;
eina_init();
matrix = eina_matrixsparse_new(MAX_ROWS, MAX_COLS,
eina_matrixsparse_free_cell_cb, data);
fail_if(matrix == NULL);
r = eina_matrixsparse_cell_idx_get(matrix, 3, 5, &cell);
fail_if(r == EINA_FALSE);
fail_if(cell != NULL);
matrixsparse_initialize(matrix, data, MAX_ROWS, MAX_COLS);
/* data fetching */
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 0);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][0]);
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 5);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][5]);
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 6);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][6]);
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 1);
fail_if(test1 != NULL);
r = eina_matrixsparse_cell_idx_get(matrix, 3, 5, &cell);
fail_if(r == EINA_FALSE);
fail_if(cell == NULL);
test1 = eina_matrixsparse_cell_data_get(cell);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][5]);
r = eina_matrixsparse_cell_position_get(cell, &row, &col);
fail_if(r == EINA_FALSE);
fail_if(row != 3 || col != 5);
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 3);
fail_if(*test1 != data[4][3]);
test1 = eina_matrixsparse_data_idx_get(matrix, 1, 3);
fail_if(*test1 != data[1][3]);
/* data changing */
r = eina_matrixsparse_data_idx_set(matrix, 1, 9, &data[1][9]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_replace(matrix, 4, 3, &value, (void **)&test1);
fail_if(r == EINA_FALSE);
fail_if(test1 == NULL);
fail_if(*test1 != data[4][3]);
data[4][3] = value;
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 3);
fail_if(test1 == NULL || *test1 != value);
r = eina_matrixsparse_cell_data_replace(cell, &value2, (void **)&test1);
fail_if(r == EINA_FALSE);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][5]);
data[3][5] = value2;
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 5);
fail_if(test1 == NULL);
fail_if(*test1 != value2);
r = eina_matrixsparse_cell_idx_get(matrix, 4, 2, &cell);
fail_if(r == EINA_FALSE || cell == NULL);
r = eina_matrixsparse_cell_data_set(cell, &value3);
fail_if(r == EINA_FALSE);
data[4][2] = value3;
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 2);
fail_if(test1 == NULL || *test1 != value3);
r = eina_matrixsparse_data_idx_replace(matrix,
6,
5,
&value4,
(void **)&test1);
fail_if(r == EINA_FALSE || test1 != NULL);
data[6][5] = value4;
/* cell deletion */
r = eina_matrixsparse_row_idx_clear(matrix, 4);
fail_if(r == EINA_FALSE);
data[4][6] = 0;
data[4][8] = 0;
data[4][2] = 0;
data[4][3] = 0;
data[4][7] = 0;
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 3);
fail_if(test1 != NULL);
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 8);
fail_if(test1 != NULL);
test1 = eina_matrixsparse_data_idx_get(matrix, 5, 3);
fail_if(*test1 != data[5][3]);
r = eina_matrixsparse_column_idx_clear(matrix, 3);
fail_if(r != EINA_TRUE);
data[0][3] = 0;
data[1][3] = 0;
data[4][3] = 0;
data[5][3] = 0;
data[6][3] = 0;
data[7][3] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 3, 5);
fail_if(r != EINA_TRUE);
data[3][5] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 3, 9);
fail_if(r != EINA_TRUE);
data[3][9] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 4, 3);
fail_if(r != EINA_TRUE);
data[4][3] = 0;
r = eina_matrixsparse_cell_idx_get(matrix, 3, 7, &cell);
fail_if(r == EINA_FALSE);
fail_if(cell == NULL);
r = eina_matrixsparse_cell_clear(cell);
fail_if(r == EINA_FALSE);
data[3][7] = 0;
r = eina_matrixsparse_cell_idx_get(matrix, 2, 7, &cell);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_cell_idx_clear(matrix, 2, 8);
fail_if(r == EINA_FALSE);
data[2][8] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 2, 7);
fail_if(r == EINA_FALSE);
data[2][7] = 0;
r = eina_matrixsparse_cell_idx_get(matrix, 7, 7, &cell);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_row_idx_clear(matrix, 8);
fail_if(r == EINA_FALSE);
data[8][8] = 0;
r = eina_matrixsparse_row_idx_clear(matrix, 7);
fail_if(r == EINA_FALSE);
data[7][3] = 0;
data[7][7] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
eina_matrixsparse_free(matrix);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_resize)
{
Eina_Matrixsparse *matrix = NULL;
Eina_Bool r;
unsigned long i, j;
unsigned long nrows, ncols;
long data[MAX_ROWS][MAX_COLS];
for (i = 0; i < MAX_ROWS; i++)
for (j = 0; j < MAX_COLS; j++)
data[i][j] = 0;
eina_init();
matrix = eina_matrixsparse_new(MAX_ROWS, MAX_COLS,
eina_matrixsparse_free_cell_cb, data);
fail_if(matrix == NULL);
/* cell insertion */
data[0][5] = 5;
data[1][0] = 10;
data[1][3] = 13;
data[1][6] = 16;
data[1][9] = 19;
data[1][8] = 18;
data[1][7] = 17;
data[2][8] = 28;
data[2][7] = 27;
data[2][6] = 26;
data[3][0] = 30;
data[3][5] = 35;
data[3][6] = 36;
data[3][7] = 37;
data[3][9] = 39;
data[3][0] = 30;
data[4][8] = 48;
data[4][2] = 42;
data[4][3] = 43;
data[4][7] = 47;
data[4][6] = 46;
data[5][3] = 53;
data[6][3] = 63;
data[6][4] = 64;
data[6][6] = 66;
data[7][3] = 73;
data[7][7] = 77;
data[8][8] = 88;
matrixsparse_initialize(matrix, data, MAX_ROWS, MAX_COLS);
eina_matrixsparse_size_get(matrix, &nrows, &ncols);
fail_if(nrows != MAX_ROWS || ncols != MAX_COLS);
r = eina_matrixsparse_size_set(matrix, nrows - 2, ncols - 2);
fail_if(r == EINA_FALSE);
data[1][9] = 0;
data[1][8] = 0;
data[2][8] = 0;
data[3][9] = 0;
data[4][8] = 0;
data[8][8] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 5, 1);
fail_if(r == EINA_FALSE);
data[0][5] = 0;
data[1][3] = 0;
data[1][6] = 0;
data[1][7] = 0;
data[2][7] = 0;
data[2][6] = 0;
data[3][5] = 0;
data[3][6] = 0;
data[3][7] = 0;
data[4][2] = 0;
data[4][3] = 0;
data[4][7] = 0;
data[4][6] = 0;
data[5][3] = 0;
data[6][3] = 0;
data[6][4] = 0;
data[6][6] = 0;
data[7][3] = 0;
data[7][7] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 1, 1);
fail_if(r == EINA_FALSE);
data[3][0] = 0;
data[1][0] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 5, 4);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 2, &data[4][2]);
fail_if(r == EINA_FALSE);
data[4][2] = 42;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 5, 1);
fail_if(r == EINA_FALSE);
data[4][2] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
eina_matrixsparse_free(matrix);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_iterators)
{
Eina_Matrixsparse *matrix = NULL;
Eina_Matrixsparse_Cell *cell = NULL;
Eina_Iterator *it = NULL;
Eina_Bool r;
long *test1, value;
unsigned long i, j;
unsigned long row, col;
long data[MAX_ROWS][MAX_COLS];
value = 0;
for (i = 0; i < MAX_ROWS; i++)
{
for (j = 0; j < MAX_COLS; j++)
{
data[i][j] = value++;
printf("%4ld ", data[i][j]);
}
printf("\n");
}
eina_init();
matrix = eina_matrixsparse_new(MAX_ROWS, MAX_COLS,
eina_matrixsparse_free_cell_cb, data);
fail_if(matrix == NULL);
r = eina_matrixsparse_data_idx_set(matrix, 3, 5, &data[3][5]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 6, &data[3][6]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 7, &data[3][7]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 9, &data[3][9]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 0, &data[3][0]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 6, &data[4][6]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 8, &data[4][8]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 2, &data[4][2]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 3, &data[4][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 7, &data[4][7]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 6, 4, &data[6][4]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 5, 3, &data[5][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 6, 3, &data[6][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 7, 3, &data[7][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 0, 3, &data[0][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 1, 3, &data[1][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 1, 6, &data[1][6]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 1, 9, &data[1][9]);
fail_if(r == EINA_FALSE);
it = eina_matrixsparse_iterator_new(matrix);
fail_if(it == NULL);
EINA_ITERATOR_FOREACH(it, cell)
{
fail_if(cell == NULL);
r = eina_matrixsparse_cell_position_get(cell, &row, &col);
fail_if(r == EINA_FALSE);
test1 = eina_matrixsparse_cell_data_get(cell);
fail_if(test1 == NULL || *test1 != data[row][col]);
}
eina_iterator_free(it);
it = eina_matrixsparse_iterator_complete_new(matrix);
fail_if(it == NULL);
EINA_ITERATOR_FOREACH(it, cell)
{
fail_if(cell == NULL);
r = eina_matrixsparse_cell_position_get(cell, &row, &col);
fail_if(r == EINA_FALSE);
test1 = eina_matrixsparse_cell_data_get(cell);
if (test1)
fail_if(*test1 != data[row][col]);
}
eina_iterator_free(it);
eina_matrixsparse_free(matrix);
eina_shutdown();
}
END_TEST
void
eina_test_matrixsparse(TCase *tc)
{
tcase_add_test(tc, eina_test_simple);
tcase_add_test(tc, eina_test_resize);
tcase_add_test(tc, eina_test_iterators);
}

View File

@ -0,0 +1,187 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "eina_suite.h"
#include "Eina.h"
static Eina_Array *_modules;
static void
_mempool_init(void)
{
eina_init();
/* force modules to be loaded in case they are not installed */
_modules = eina_module_list_get(NULL,
PACKAGE_BUILD_DIR "/src/modules",
EINA_TRUE,
NULL,
NULL);
eina_module_list_load(_modules);
}
static void
_mempool_shutdown(void)
{
eina_module_list_free(_modules);
/* TODO delete the list */
eina_shutdown();
}
static void
_eina_mempool_test(Eina_Mempool *mp, Eina_Bool with_realloc, Eina_Bool with_gc)
{
int *tbl[512];
int i;
fail_if(!mp);
for (i = 0; i < 512; ++i)
{
tbl[i] = eina_mempool_malloc(mp, sizeof (int));
fail_if(!tbl[i]);
*tbl[i] = i;
}
for (i = 0; i < 512; ++i)
fail_if(*tbl[i] != i);
for (i = 0; i < 256; ++i)
eina_mempool_free(mp, tbl[i]);
if (with_realloc)
fail_if(eina_mempool_realloc(mp, tbl[500], 25) == NULL);
else
fail_if(eina_mempool_realloc(mp, tbl[500], 25) != NULL);
if (with_gc)
{
eina_mempool_gc(mp);
eina_mempool_statistics(mp);
}
eina_mempool_del(mp);
}
#ifdef EINA_BUILD_CHAINED_POOL
START_TEST(eina_mempool_chained_mempool)
{
Eina_Mempool *mp;
_mempool_init();
mp = eina_mempool_add("chained_mempool", "test", NULL, sizeof (int), 256);
_eina_mempool_test(mp, EINA_FALSE, EINA_FALSE);
_mempool_shutdown();
}
END_TEST
#endif
#ifdef EINA_BUILD_PASS_THROUGH
START_TEST(eina_mempool_pass_through)
{
Eina_Mempool *mp;
_mempool_init();
mp = eina_mempool_add("pass_through", "test", NULL, sizeof (int), 8, 0);
_eina_mempool_test(mp, EINA_TRUE, EINA_FALSE);
_mempool_shutdown();
}
END_TEST
#endif
#ifdef EINA_BUILD_FIXED_BITMAP
START_TEST(eina_mempool_fixed_bitmap)
{
Eina_Mempool *mp;
_mempool_init();
mp = eina_mempool_add("fixed_bitmap", "test", NULL, sizeof (int));
_eina_mempool_test(mp, EINA_FALSE, EINA_FALSE);
_mempool_shutdown();
}
END_TEST
#endif
#ifdef EINA_BUILD_EMEMOA_FIXED
START_TEST(eina_mempool_ememoa_fixed)
{
Eina_Mempool *mp;
_mempool_init();
mp = eina_mempool_add("ememoa_fixed", "test", NULL, sizeof (int), 8, 0);
_eina_mempool_test(mp, EINA_FALSE, EINA_TRUE);
_mempool_shutdown();
}
END_TEST
#endif
#ifdef EINA_BUILD_EMEMOA_UNKNOWN
START_TEST(eina_mempool_ememoa_unknown)
{
Eina_Mempool *mp;
_mempool_init();
mp = eina_mempool_add("ememoa_unknown",
"test",
NULL,
0,
2,
sizeof (int),
8,
sizeof (int) * 2,
8);
_eina_mempool_test(mp, EINA_TRUE, EINA_TRUE);
_mempool_shutdown();
}
END_TEST
#endif
void
eina_test_mempool(TCase *tc)
{
#ifdef EINA_BUILD_CHAINED_POOL
tcase_add_test(tc, eina_mempool_chained_mempool);
#endif
#ifdef EINA_BUILD_PASS_THROUGH
tcase_add_test(tc, eina_mempool_pass_through);
#endif
#ifdef EINA_BUILD_FIXED_BITMAP
tcase_add_test(tc, eina_mempool_fixed_bitmap);
#endif
#ifdef EINA_BUILD_EMEMOA_FIXED
tcase_add_test(tc, eina_mempool_ememoa_fixed);
#endif
#ifdef EINA_BUILD_EMEMOA_UNKNOWN
tcase_add_test(tc, eina_mempool_ememoa_unknown);
#endif
}

View File

@ -0,0 +1,70 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
static Eina_Bool list_cb(Eina_Module *m, void *data __UNUSED__)
{
int *sym;
const char *file;
/* the reference count */
eina_module_load(m);
/* get */
sym = eina_module_symbol_get(m, "dummy_symbol");
fail_if(!sym);
fail_if(*sym != 0xbad);
file = eina_module_file_get(m);
fail_if(!file);
eina_module_unload(m);
return EINA_TRUE;
}
START_TEST(eina_module_load_unload)
{
Eina_Array *_modules;
eina_init();
_modules = eina_module_list_get(NULL,
PACKAGE_BUILD_DIR "/src/tests/",
EINA_TRUE,
&list_cb,
NULL);
fail_if(!_modules);
eina_module_list_load(_modules);
eina_module_list_unload(_modules);
eina_module_list_free(_modules);
/* TODO delete the list */
eina_shutdown();
}
END_TEST
void
eina_test_module(TCase *tc)
{
tcase_add_test(tc, eina_module_load_unload);
}

View File

@ -0,0 +1,22 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "Eina.h"
Eina_Bool dummy_module_init(void)
{
return EINA_TRUE;
}
void dummy_module_shutdown(void)
{
}
EAPI int dummy_symbol = 0xbad;
EINA_MODULE_INIT(dummy_module_init);
EINA_MODULE_SHUTDOWN(dummy_module_shutdown);

View File

@ -0,0 +1,195 @@
/* EINA - EFL data type library
* Copyright (C) 2010 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
static Eina_Quad_Direction
_eina_quadtree_rectangle_vert(const void *object, size_t middle)
{
const Eina_Rectangle *r = object;
if (r->y + r->h < (int)middle)
return EINA_QUAD_LEFT;
if (r->y > (int)middle)
return EINA_QUAD_RIGHT;
return EINA_QUAD_BOTH;
}
static Eina_Quad_Direction
_eina_quadtree_rectangle_hort(const void *object, size_t middle)
{
const Eina_Rectangle *r = object;
if (r->x + r->w < (int)middle)
return EINA_QUAD_LEFT;
if (r->x > (int)middle)
return EINA_QUAD_RIGHT;
return EINA_QUAD_BOTH;
}
START_TEST(eina_quadtree_collision)
{
struct
{
Eina_Rectangle r;
Eina_QuadTree_Item *item;
} objects[] = {
{ { 10, 10, 30, 30 }, NULL },
{ { 20, 20, 30, 30 }, NULL },
{ { 5, 30, 30, 30 }, NULL },
{ { 70, 130, 100, 100 }, NULL },
{ { 10, 220, 50, 40 }, NULL },
{ { 310, 20, 50, 30 }, NULL },
{ { 300, 220, 40, 40 }, NULL },
{ { 500, 150, 40, 40 }, NULL },
{ { 500, 220, 40, 40 }, NULL },
{ { 330, 250, 40, 40 }, NULL },
{ { 300, 400, 40, 40 }, NULL },
{ { 10, 400, 40, 40 }, NULL },
{ { 0, 0, 0, 0 }, NULL }
};
struct
{
Eina_Rectangle r;
int count;
int result[20];
} tests [] = {
{ { 600, 400, 40, 40 }, 4, { 4, 6, 8, 10 } },
{ { 20, 30, 10, 10 }, 7, { 0, 1, 2, 4, 5, 6, 8 } },
{ { 0, 0, 0, 0 }, -1, {} },
};
int hidden[] = { 4, 5, 6, 8, 10 };
int show[] = { 0, 1, 2 };
Eina_QuadTree *q;
Eina_Inlist *head;
Eina_Rectangle *r;
int count;
int i;
fail_if(!eina_init());
q = eina_quadtree_new(640, 480,
_eina_quadtree_rectangle_vert,
_eina_quadtree_rectangle_hort);
fail_if(!q);
for (i = 0; objects[i].r.w != 0 && objects[i].r.h != 0; ++i)
{
objects[i].item = eina_quadtree_add(q, &objects[i].r);
fail_if(!objects[i].item);
fail_if(!eina_quadtree_show(objects[i].item));
}
eina_quadtree_resize(q, 640, 480);
for (i = 0; tests[i].count != -1; ++i)
{
head = eina_quadtree_collide(q,
tests[i].r.x, tests[i].r.y,
tests[i].r.w, tests[i].r.h);
count = 0;
while (head)
{
int k;
r = eina_quadtree_object(head);
for (k = 0; k < tests[i].count; ++k)
{
if (&objects[tests[i].result[k]].r == r)
break;
}
fail_if(k == tests[i].count);
head = head->next;
count++;
}
fail_if(count != tests[i].count);
}
for (i = 0; i < (int)(sizeof (hidden) / sizeof (int)); ++i)
eina_quadtree_hide(objects[hidden[i]].item);
for (i = 0; i < (int)(sizeof (show) / sizeof (int)); ++i)
eina_quadtree_show(objects[show[i]].item);
head = eina_quadtree_collide(q,
tests[1].r.x, tests[1].r.y,
tests[1].r.w, tests[1].r.h);
count = 0;
while (head)
{
r = eina_quadtree_object(head);
fail_if(r != &objects[tests[1].result[show[count]]].r);
head = head->next;
count++;
}
fail_if(count != 3);
eina_quadtree_cycle(q);
eina_quadtree_show(objects[4].item);
eina_quadtree_increase(objects[4].item);
eina_quadtree_show(objects[5].item);
eina_quadtree_increase(objects[5].item);
eina_quadtree_del(objects[5].item);
eina_quadtree_change(objects[10].item);
eina_quadtree_increase(objects[10].item);
eina_quadtree_resize(q, 641, 480);
head = eina_quadtree_collide(q,
tests[0].r.x, tests[0].r.y,
tests[0].r.w, tests[0].r.h);
count = 0;
while (head)
{
r = eina_quadtree_object(head);
head = head->next;
count++;
}
fail_if(count != 1);
eina_quadtree_free(q);
eina_shutdown();
}
END_TEST
void
eina_test_quadtree(TCase *tc)
{
tcase_add_test(tc, eina_quadtree_collision);
}

View File

@ -0,0 +1,452 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "eina_suite.h"
#include "Eina.h"
static inline Eina_Bool
_eina_rbtree_is_red(Eina_Rbtree *tree)
{
return tree != NULL && tree->color == EINA_RBTREE_RED;
}
static int
_eina_rbtree_black_height(Eina_Rbtree *tree, Eina_Rbtree_Cmp_Node_Cb cmp)
{
Eina_Rbtree *left;
Eina_Rbtree *right;
Eina_Rbtree_Direction dir;
int left_height;
int right_height;
if (!tree)
return 1;
left = tree->son[EINA_RBTREE_LEFT];
right = tree->son[EINA_RBTREE_RIGHT];
/* Consecutive red links. */
fail_if(_eina_rbtree_is_red(tree) &&
(_eina_rbtree_is_red(left) || _eina_rbtree_is_red(right)));
left_height = _eina_rbtree_black_height(left, cmp);
right_height = _eina_rbtree_black_height(right, cmp);
/* Check binary search tree. */
if (left)
{
dir = cmp(tree, left, NULL);
fail_if(dir != EINA_RBTREE_LEFT);
}
if (right)
{
dir = cmp(tree, right, NULL);
fail_if(dir != EINA_RBTREE_RIGHT);
}
/* Check black height */
if (left_height != right_height)
fprintf(stderr, "%i != %i\n", left_height, right_height);
fail_if(left_height != right_height);
return _eina_rbtree_is_red(tree) ? left_height : left_height + 1;
}
typedef struct _Eina_Rbtree_Int Eina_Rbtree_Int;
struct _Eina_Rbtree_Int
{
Eina_Rbtree node;
int value;
};
static Eina_Rbtree_Direction
eina_rbtree_int_cmp(const Eina_Rbtree_Int *left,
const Eina_Rbtree_Int *right,
__UNUSED__ void *data)
{
fail_if(!left);
fail_if(!right);
if (left->value < right->value)
return EINA_RBTREE_LEFT;
return EINA_RBTREE_RIGHT;
}
static int
eina_rbtree_int_key(const Eina_Rbtree_Int *node,
const int *key,
__UNUSED__ int length,
__UNUSED__ void *data)
{
fail_if(!node);
return node->value - *key;
}
static Eina_Rbtree_Int *
_eina_rbtree_int_new(int value)
{
Eina_Rbtree_Int *it;
it = malloc(sizeof (Eina_Rbtree_Int));
fail_if(!it);
it->value = value;
return it;
}
START_TEST(eina_rbtree_insertion)
{
Eina_Rbtree_Int *root = NULL;
Eina_Rbtree_Int *item;
int i;
srand(time(NULL));
for (i = 0; i < 500; ++i)
{
item = _eina_rbtree_int_new(rand());
root = (Eina_Rbtree_Int *)eina_rbtree_inline_insert(
&root->node,
&item->node,
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp),
NULL);
}
_eina_rbtree_black_height(&root->node,
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp));
}
END_TEST
START_TEST(eina_rbtree_lookup)
{
Eina_Rbtree_Int *root = NULL;
Eina_Rbtree_Int *item;
int list[] = { 50, 100, 10, 43, 23 };
unsigned int i;
for (i = 0; i < sizeof (list) / sizeof (int); ++i)
{
item = _eina_rbtree_int_new(list[i]);
root = (Eina_Rbtree_Int *)eina_rbtree_inline_insert(
&root->node,
&item->node,
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp),
NULL);
}
item = (Eina_Rbtree_Int *)eina_rbtree_inline_lookup(&root->node,
&list[0],
sizeof(int),
EINA_RBTREE_CMP_KEY_CB(
eina_rbtree_int_key),
NULL);
fail_if(!item);
i = 42;
item =
(Eina_Rbtree_Int *)eina_rbtree_inline_lookup(&root->node,
&i,
sizeof(int),
EINA_RBTREE_CMP_KEY_CB(
eina_rbtree_int_key),
NULL);
fail_if(item);
}
END_TEST
START_TEST(eina_rbtree_remove)
{
Eina_Rbtree_Int *root = NULL;
Eina_Rbtree_Int *item;
Eina_Array *ea;
Eina_Array_Iterator it;
unsigned int i;
eina_init();
ea = eina_array_new(11);
fail_if(!ea);
srand(time(NULL));
for (i = 0; i < 500; ++i)
{
item = _eina_rbtree_int_new(rand());
eina_array_push(ea, item);
root = (Eina_Rbtree_Int *)eina_rbtree_inline_insert(
&root->node,
&item->node,
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp),
NULL);
}
_eina_rbtree_black_height(&root->node,
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
EINA_ARRAY_ITER_NEXT(ea, i, item, it)
{
root = (Eina_Rbtree_Int *)eina_rbtree_inline_remove(
&root->node,
&item->node,
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp),
NULL);
_eina_rbtree_black_height(&root->node,
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
}
fail_if(root != NULL);
eina_shutdown();
}
END_TEST
START_TEST(eina_rbtree_simple_remove)
{
Eina_Rbtree *root = NULL;
Eina_Rbtree *lookup;
int i;
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
10),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
42),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
69),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1337),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
_eina_rbtree_black_height(root,
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
fail_if(root == NULL);
i = 69;
lookup = eina_rbtree_inline_lookup(root,
&i,
sizeof (int),
EINA_RBTREE_CMP_KEY_CB(
eina_rbtree_int_key),
NULL);
_eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
fail_if(lookup == NULL);
root =
eina_rbtree_inline_remove(root, lookup, EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
_eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
}
END_TEST
START_TEST(eina_rbtree_simple_remove2)
{
Eina_Rbtree *root = NULL;
Eina_Rbtree *lookup;
int i;
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
10),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
42),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
69),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1337),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
77),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
75),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
81),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
_eina_rbtree_black_height(root,
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
fail_if(root == NULL);
i = 69;
lookup = eina_rbtree_inline_lookup(root,
&i,
sizeof (int),
EINA_RBTREE_CMP_KEY_CB(
eina_rbtree_int_key),
NULL);
_eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
fail_if(lookup == NULL);
root =
eina_rbtree_inline_remove(root, lookup, EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
_eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
}
END_TEST
START_TEST(eina_rbtree_simple_remove3)
{
Eina_Rbtree *root = NULL;
Eina_Rbtree *lookup;
int i;
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1113497590),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
499187507),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1693860487),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
26211080),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
797272577),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1252184882),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1448158229),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1821884856),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
346086006),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
936357333),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1462073936),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1717320055),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
root =
eina_rbtree_inline_insert(root, (Eina_Rbtree *)_eina_rbtree_int_new(
1845524606),
EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
_eina_rbtree_black_height(root,
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
fail_if(root == NULL);
i = 1113497590;
lookup = eina_rbtree_inline_lookup(root,
&i,
sizeof (int),
EINA_RBTREE_CMP_KEY_CB(
eina_rbtree_int_key),
NULL);
_eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
fail_if(lookup == NULL);
root =
eina_rbtree_inline_remove(root, lookup, EINA_RBTREE_CMP_NODE_CB(
eina_rbtree_int_cmp), NULL);
_eina_rbtree_black_height(root, EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
}
END_TEST
void
eina_test_rbtree(TCase *tc)
{
tcase_add_test(tc, eina_rbtree_insertion);
tcase_add_test(tc, eina_rbtree_lookup);
tcase_add_test(tc, eina_rbtree_remove);
tcase_add_test(tc, eina_rbtree_simple_remove);
tcase_add_test(tc, eina_rbtree_simple_remove2);
tcase_add_test(tc, eina_rbtree_simple_remove3);
}

View File

@ -0,0 +1,115 @@
/* EINA - EFL data type library
* Copyright (C) 2007-2008 Cedric BAIL, Carsten Haitzler
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(eina_rectangle_pool)
{
Eina_Rectangle_Pool *pool;
Eina_Rectangle *rects[8][8];
int x;
int y;
int w;
int h;
fail_if(!eina_init());
pool = eina_rectangle_pool_new(256, 256);
fail_if(pool == NULL);
eina_rectangle_pool_data_set(pool, rects);
fail_if(eina_rectangle_pool_data_get(pool) != rects);
fail_if(eina_rectangle_pool_request(pool, 1024, 1024) != NULL);
for (x = 0; x < 8; x++)
for (y = 0; y < 8; y++)
{
rects[x][y] = eina_rectangle_pool_request(pool, 32, 32);
fail_if(rects[x][y] == NULL);
}
fail_if(eina_rectangle_pool_count(pool) != 64);
fail_if(eina_rectangle_pool_get(rects[0][0]) != pool);
fail_if(eina_rectangle_pool_geometry_get(pool, &w, &h) != EINA_TRUE);
fail_if(w != 256 || h != 256);
fail_if(eina_rectangle_pool_request(pool, 32, 32) != NULL);
fail_if(eina_rectangle_pool_request(pool, 1024, 1024) != NULL);
for (x = 0; x < 8; x++)
eina_rectangle_pool_release(rects[0][x]);
fail_if(eina_rectangle_pool_request(pool, 16, 16) == NULL);
eina_rectangle_pool_free(pool);
eina_shutdown();
}
END_TEST
START_TEST(eina_rectangle_intersect)
{
Eina_Rectangle r1, r2, r3, r4, rd;
fail_if(!eina_init());
EINA_RECTANGLE_SET(&r1, 10, 10, 50, 50);
EINA_RECTANGLE_SET(&r2, 20, 20, 20, 20);
EINA_RECTANGLE_SET(&r3, 0, 0, 10, 10);
EINA_RECTANGLE_SET(&r4, 30, 30, 50, 50);
rd = r1;
fail_if(eina_rectangle_intersection(&rd, &r3));
fail_if(!eina_rectangle_intersection(&rd, &r2));
fail_if(rd.x != r2.x
|| rd.y != r2.y
|| rd.w != r2.w
|| rd.h != r2.h);
rd = r1;
fail_if(!eina_rectangle_intersection(&rd, &r4));
fail_if(rd.x != 30
|| rd.y != 30
|| rd.w != 30
|| rd.h != 30);
eina_shutdown();
}
END_TEST
void
eina_test_rectangle(TCase *tc)
{
tcase_add_test(tc, eina_rectangle_pool);
tcase_add_test(tc, eina_rectangle_intersect);
}

View File

@ -0,0 +1,85 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if defined(EFL_HAVE_THREADS) && defined __linux__
#include <pthread.h>
#include <errno.h>
#include <sys/resource.h>
#endif
#include "eina_suite.h"
#include "Eina.h"
#if defined(EFL_HAVE_THREADS) && defined __linux__
/*
* TODO: Test if RT priorities are right. However, make check should be run as
* root.
*/
static void *
_thread_run(void *arg __UNUSED__)
{
int niceval = getpriority(PRIO_PROCESS, 0);
int niceval2;
eina_sched_prio_drop();
niceval2 = getpriority(PRIO_PROCESS, 0);
fail_if((niceval2 != 19) && (niceval2 != niceval+5));
return NULL;
}
START_TEST(eina_test_sched_prio_drop)
{
int niceval = getpriority(PRIO_PROCESS, 0);
int niceval2;
pthread_t tid;
eina_init();
pthread_create(&tid, NULL, _thread_run, NULL);
niceval2 = getpriority(PRIO_PROCESS, 0);
/* niceness of main thread should not have changed */
fail_if(niceval2 != niceval);
pthread_join(tid, NULL);
/* niceness of main thread should not have changed */
fail_if(niceval2 != niceval);
eina_shutdown();
}
END_TEST
#else
START_TEST(eina_test_sched_prio_drop)
{
fprintf(stderr, "scheduler priority is not supported by your configuration.\n");
}
END_TEST
#endif
void
eina_test_sched(TCase *tc)
{
tcase_add_test(tc, eina_test_sched_prio_drop);
}

View File

@ -0,0 +1,181 @@
/* EINA - EFL data type library
* Copyright (C) 2010 Gustavo Sverzut Barbieri
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(str_simple)
{
eina_init();
fail_if(!eina_str_has_prefix("", ""));
fail_if(!eina_str_has_prefix("x", "x"));
fail_if(!eina_str_has_prefix("xab", "x"));
fail_if(!eina_str_has_prefix("xab", "xab"));
fail_if(eina_str_has_prefix("x", "xab"));
fail_if(eina_str_has_prefix("xab", "xyz"));
fail_if(eina_str_has_prefix("", "x"));
fail_if(eina_str_has_prefix("X", "x"));
fail_if(eina_str_has_prefix("xAb", "X"));
fail_if(eina_str_has_prefix("xAb", "xab"));
fail_if(!eina_str_has_suffix("", ""));
fail_if(!eina_str_has_suffix("x", "x"));
fail_if(!eina_str_has_suffix("abx", "x"));
fail_if(!eina_str_has_suffix("xab", "xab"));
fail_if(eina_str_has_suffix("x", "xab"));
fail_if(eina_str_has_suffix("xab", "xyz"));
fail_if(eina_str_has_suffix("", "x"));
fail_if(eina_str_has_suffix("X", "x"));
fail_if(eina_str_has_suffix("aBx", "X"));
fail_if(eina_str_has_suffix("xaB", "Xab"));
fail_if(!eina_str_has_extension("", ""));
fail_if(!eina_str_has_extension("x", "x"));
fail_if(!eina_str_has_extension("abx", "x"));
fail_if(!eina_str_has_extension("xab", "xab"));
fail_if(!eina_str_has_extension("x", "X"));
fail_if(!eina_str_has_extension("abx", "X"));
fail_if(!eina_str_has_extension("xab", "Xab"));
fail_if(!eina_str_has_extension("X", "X"));
fail_if(!eina_str_has_extension("aBx", "X"));
fail_if(!eina_str_has_extension("xaB", "Xab"));
fail_if(eina_str_has_extension("x", "xab"));
fail_if(eina_str_has_extension("xab", "xyz"));
fail_if(eina_str_has_extension("", "x"));
fail_if(eina_str_has_extension("x", "xAb"));
fail_if(eina_str_has_extension("xab", "xYz"));
fail_if(eina_str_has_extension("", "x"));
fail_if(eina_strlen_bounded("abc", 1024) != strlen("abc"));
fail_if(eina_strlen_bounded("abc", 2) != (size_t)-1);
eina_shutdown();
}
END_TEST
START_TEST(str_split)
{
char **result;
unsigned int elements;
eina_init();
result = eina_str_split_full("nomatch", "", -1, &elements);
fail_if(result != NULL);
fail_if(elements != 0);
result = eina_str_split_full("nomatch", "x", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 1);
fail_if(strcmp(result[0], "nomatch") != 0);
free(result[0]);
free(result);
result = eina_str_split_full("nomatch", "xyz", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 1);
fail_if(strcmp(result[0], "nomatch") != 0);
free(result[0]);
free(result);
result = eina_str_split_full("match:match:match", ":", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 3);
while (elements >= 1)
{
elements--;
fail_if(strcmp(result[elements], "match") != 0);
}
free(result[0]);
free(result);
result = eina_str_split_full("a:b:c", ":", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 3);
fail_if(strcmp(result[0], "a") != 0);
fail_if(strcmp(result[1], "b") != 0);
fail_if(strcmp(result[2], "c") != 0);
free(result[0]);
free(result);
result = eina_str_split_full("a:b:", ":", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 3);
fail_if(strcmp(result[0], "a") != 0);
fail_if(strcmp(result[1], "b") != 0);
fail_if(strcmp(result[2], "") != 0);
free(result[0]);
free(result);
result = eina_str_split_full(":b:c", ":", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 3);
fail_if(strcmp(result[0], "") != 0);
fail_if(strcmp(result[1], "b") != 0);
fail_if(strcmp(result[2], "c") != 0);
free(result[0]);
free(result);
result = eina_str_split_full(":", ":", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 2);
fail_if(strcmp(result[0], "") != 0);
fail_if(strcmp(result[1], "") != 0);
free(result[0]);
free(result);
result = eina_str_split_full("a", "!!!!!!!!!", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 1);
fail_if(strcmp(result[0], "a") != 0);
free(result[0]);
free(result);
result = eina_str_split_full("aaba", "ab", -1, &elements);
fail_if(result == NULL);
fail_if(elements != 2);
fail_if(strcmp(result[0], "a") != 0);
fail_if(strcmp(result[1], "a") != 0);
free(result[0]);
free(result);
eina_shutdown();
}
END_TEST
void
eina_test_str(TCase *tc)
{
tcase_add_test(tc, str_simple);
tcase_add_test(tc, str_split);
}

View File

@ -0,0 +1,409 @@
/* EINA - EFL data type library
* Copyright (C) 2010 Sebastian Dransfeld
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
START_TEST(strbuf_simple)
{
Eina_Strbuf *buf;
char *txt;
#define TEXT \
"This test should be so long that it is longer than the initial size of strbuf"
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
eina_strbuf_append(buf, TEXT);
fail_if(strcmp(eina_strbuf_string_get(buf), TEXT));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
eina_strbuf_append(buf, TEXT);
fail_if(strcmp(eina_strbuf_string_get(buf), TEXT TEXT));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
txt = eina_strbuf_string_steal(buf);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(txt, TEXT TEXT));
free(txt);
fail_if(eina_strbuf_length_get(buf) != 0);
fail_if(!strcmp(eina_strbuf_string_get(buf), TEXT TEXT));
eina_strbuf_append(buf, TEXT);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
eina_strbuf_reset(buf);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(eina_strbuf_length_get(buf) != 0);
fail_if(!strcmp(eina_strbuf_string_get(buf), TEXT));
eina_strbuf_free(buf);
eina_shutdown();
#undef TEXT
}
END_TEST
START_TEST(strbuf_remove)
{
Eina_Strbuf *buf;
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
eina_strbuf_append(buf, "123 456 789 abc");
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
eina_strbuf_remove(buf, 0, 4);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "456 789 abc"));
eina_strbuf_remove(buf, 8, 1000);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "456 789 "));
eina_strbuf_remove(buf, 7, eina_strbuf_length_get(buf));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "456 789"));
eina_strbuf_remove(buf, 2, 4);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "45789"));
eina_strbuf_remove(buf, 4, 1);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "45789"));
eina_strbuf_remove(buf, 0, eina_strbuf_length_get(buf));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), ""));
#define TEXT \
"This test should be so long that it is longer than the initial size of strbuf"
eina_strbuf_append(buf, TEXT TEXT);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
eina_strbuf_remove(buf, 0, eina_strbuf_length_get(buf) - 1);
fail_if(strcmp(eina_strbuf_string_get(buf), "f"));
#undef TEXT
eina_strbuf_free(buf);
eina_shutdown();
}
END_TEST
START_TEST(strbuf_append)
{
Eina_Strbuf *buf;
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
eina_strbuf_append(buf, "abc");
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "abc"));
eina_strbuf_reset(buf);
eina_strbuf_append_escaped(buf, "abc");
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "abc"));
eina_strbuf_reset(buf);
eina_strbuf_append_escaped(buf, "abc '\\");
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "abc\\ \\'\\\\"));
eina_strbuf_reset(buf);
eina_strbuf_append_n(buf, "abc", 2);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "ab"));
eina_strbuf_reset(buf);
eina_strbuf_append_char(buf, 'a');
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "a"));
eina_strbuf_reset(buf);
eina_strbuf_append_length(buf, "something", strlen("something"));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "something"));
eina_strbuf_reset(buf);
eina_strbuf_append_length(buf, "somethingELSE", strlen("something"));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "something"));
eina_strbuf_reset(buf);
eina_strbuf_free(buf);
eina_shutdown();
}
END_TEST
START_TEST(strbuf_insert)
{
Eina_Strbuf *buf;
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
eina_strbuf_insert(buf, "abc", 10);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "abc"));
eina_strbuf_insert(buf, "123", 0);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "123abc"));
eina_strbuf_insert(buf, "xyz", eina_strbuf_length_get(buf));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "123abcxyz"));
eina_strbuf_insert(buf, "xyz", 1);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "1xyz23abcxyz"));
eina_strbuf_insert_n(buf, "ABCDEF", 2, 1);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "1ABxyz23abcxyz"));
eina_strbuf_insert_n(buf, "EINA", 2, 3);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "1ABEIxyz23abcxyz"));
eina_strbuf_insert_escaped(buf, "678", 3);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strncmp(eina_strbuf_string_get(buf) + 3, "678", 3));
eina_strbuf_insert_escaped(buf, "089 '\\", 9);
fail_if(strlen(eina_strbuf_string_get(
buf)) != eina_strbuf_length_get(buf));
fail_if(strncmp(eina_strbuf_string_get(buf) + 9,
"089\\ \\'\\\\",
strlen("089\\ \\'\\\\")));
eina_strbuf_reset(buf);
eina_strbuf_free(buf);
eina_shutdown();
}
END_TEST
START_TEST(strbuf_replace)
{
Eina_Strbuf *buf;
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
eina_strbuf_append(buf, "aaa");
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "aaa"));
fail_if(!eina_strbuf_replace(buf, "a", "b", 1));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "baa"));
fail_if(eina_strbuf_replace_all(buf, "a", "b") != 2);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "bbb"));
fail_if(!eina_strbuf_replace(buf, "b", "cc", 2));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "bccb"));
fail_if(eina_strbuf_replace_all(buf, "c", "aa") != 2);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "baaaab"));
fail_if(eina_strbuf_replace(buf, "c", "aa", 0));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "baaaab"));
fail_if(eina_strbuf_replace(buf, "c", "aa", 2));
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "baaaab"));
fail_if(eina_strbuf_replace_all(buf, "c", "aa") != 0);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "baaaab"));
eina_strbuf_free(buf);
eina_shutdown();
}
END_TEST
START_TEST(strbuf_realloc)
{
Eina_Strbuf *buf;
char pattern[1024 * 16];
unsigned int i;
size_t sz;
for (i = 0; i < sizeof(pattern) - 1; i++)
pattern[i] = 'a' + (i % 26);
pattern[i] = '\0';
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
sz = 0;
eina_strbuf_append_length(buf, pattern, 1);
fail_if(eina_strbuf_length_get(buf) != sz + 1);
fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 1));
sz += 1;
eina_strbuf_append_length(buf, pattern, 32);
fail_if(eina_strbuf_length_get(buf) != sz + 32);
fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 32));
sz += 32;
eina_strbuf_append_length(buf, pattern, 64);
fail_if(eina_strbuf_length_get(buf) != sz + 64);
fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 64));
sz += 64;
eina_strbuf_append_length(buf, pattern, 128);
fail_if(eina_strbuf_length_get(buf) != sz + 128);
fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 128));
sz += 128;
eina_strbuf_append_length(buf, pattern, 4096);
fail_if(eina_strbuf_length_get(buf) != sz + 4096);
fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 4096));
sz += 4096;
eina_strbuf_append_length(buf, pattern, sizeof(pattern) - 1);
fail_if(eina_strbuf_length_get(buf) != sz + sizeof(pattern) - 1);
fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, sizeof(pattern) -
1));
sz += sizeof(pattern) - 1;
eina_strbuf_remove(buf, 1024, 1024 + 1234);
fail_if(eina_strbuf_length_get(buf) != sz - 1234);
sz -= 1234;
eina_strbuf_remove(buf, 0, 0 + 8192);
fail_if(eina_strbuf_length_get(buf) != sz - 8192);
sz -= 8192;
eina_strbuf_remove(buf, 0, 0 + 32);
fail_if(eina_strbuf_length_get(buf) != sz - 32);
sz -= 32;
eina_strbuf_free(buf);
eina_shutdown();
}
END_TEST
START_TEST(strbuf_append_realloc)
{
Eina_Strbuf *buf;
const size_t runs = 40960;
const char target_pattern[] = "stringstrsstr";
const char *str;
size_t i, target_pattern_size;
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
for (i = 0; i < runs; i++)
{
fail_if(!eina_strbuf_append(buf, "string"));
fail_if(!eina_strbuf_append_n(buf, "string", 3));
fail_if(!eina_strbuf_append_char(buf, 's'));
fail_if(!eina_strbuf_append_length(buf, "string", 3));
}
target_pattern_size = strlen(target_pattern);
fail_if(eina_strbuf_length_get(buf) != (runs * target_pattern_size));
str = eina_strbuf_string_get(buf);
fail_if(str == NULL);
for (i = 0; i < runs; i++, str += target_pattern_size)
fail_if(memcmp(str, target_pattern, target_pattern_size));
eina_strbuf_free(buf);
eina_shutdown();
}
END_TEST
START_TEST(strbuf_prepend_realloc)
{
Eina_Strbuf *buf;
const size_t runs = 40960;
const char target_pattern[] = "strsstrstring";
const char *str;
size_t i, target_pattern_size;
eina_init();
buf = eina_strbuf_new();
fail_if(!buf);
for (i = 0; i < runs; i++)
{
fail_if(!eina_strbuf_prepend(buf, "string"));
fail_if(!eina_strbuf_prepend_n(buf, "string", 3));
fail_if(!eina_strbuf_prepend_char(buf, 's'));
fail_if(!eina_strbuf_prepend_length(buf, "string", 3));
}
target_pattern_size = strlen(target_pattern);
fail_if(eina_strbuf_length_get(buf) != (runs * target_pattern_size));
str = eina_strbuf_string_get(buf);
fail_if(str == NULL);
for (i = 0; i < runs; i++, str += target_pattern_size)
fail_if(memcmp(str, target_pattern, target_pattern_size));
eina_strbuf_free(buf);
eina_shutdown();
}
END_TEST
void
eina_test_strbuf(TCase *tc)
{
tcase_add_test(tc, strbuf_simple);
tcase_add_test(tc, strbuf_remove);
tcase_add_test(tc, strbuf_append);
tcase_add_test(tc, strbuf_insert);
tcase_add_test(tc, strbuf_replace);
tcase_add_test(tc, strbuf_realloc);
tcase_add_test(tc, strbuf_append_realloc);
tcase_add_test(tc, strbuf_prepend_realloc);
}

View File

@ -0,0 +1,201 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "eina_suite.h"
#include "Eina.h"
#define TEST0 "test/0"
#define TEST1 "test/1"
START_TEST(eina_stringshare_simple)
{
const char *t0;
const char *t1;
eina_init();
t0 = eina_stringshare_add(TEST0);
t1 = eina_stringshare_add(TEST1);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(strcmp(t0, TEST0) != 0);
fail_if(strcmp(t1, TEST1) != 0);
fail_if((int)strlen(TEST0) != eina_stringshare_strlen(t0));
fail_if((int)strlen(TEST1) != eina_stringshare_strlen(t1));
t0 = eina_stringshare_ref(t0);
fail_if(t0 == NULL);
fail_if((int)strlen(TEST0) != eina_stringshare_strlen(t0));
eina_stringshare_del(t0);
eina_stringshare_del(t0);
eina_stringshare_del(t1);
eina_shutdown();
}
END_TEST
START_TEST(eina_stringshare_small)
{
char buf[4];
int i;
eina_init();
for (i = 0; i < 3; i++)
{
const char *t0, *t1;
int j;
for (j = 0; j < i; j++)
{
char c;
for (c = 'a'; c <= 'z'; c++)
buf[j] = c;
}
buf[i] = '\0';
t0 = eina_stringshare_add(buf);
t1 = eina_stringshare_add(buf);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(t0 != t1);
fail_if(strcmp(t0, buf) != 0);
fail_if((int)strlen(buf) != eina_stringshare_strlen(t0));
fail_if((int)strlen(buf) != eina_stringshare_strlen(t1));
eina_stringshare_del(t0);
eina_stringshare_del(t1);
}
eina_shutdown();
}
END_TEST
START_TEST(eina_stringshare_test_share)
{
const char *t0;
const char *t1;
eina_init();
t0 = eina_stringshare_add(TEST0);
t1 = eina_stringshare_add(TEST0);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(strcmp(t0, TEST0) != 0);
fail_if(strcmp(t1, TEST0) != 0);
fail_if(t0 != t1);
fail_if((int)strlen(t0) != eina_stringshare_strlen(t0));
eina_stringshare_del(t0);
eina_stringshare_del(t1);
eina_shutdown();
}
END_TEST
START_TEST(eina_stringshare_putstuff)
{
const char *tmp;
int i;
eina_init();
for (i = 10000; i > 0; --i)
{
char build[64] = "string_";
eina_convert_xtoa(i, build + 7);
tmp = eina_stringshare_add(build);
fail_if(tmp != eina_stringshare_add(build));
}
eina_shutdown();
}
END_TEST
START_TEST(eina_stringshare_collision)
{
Eina_Array *ea;
char buffer[50];
int i;
srand(time(NULL));
eina_init();
ea = eina_array_new(256);
fail_if(!ea);
for (i = 0; i < 10000; ++i)
{
eina_convert_itoa(rand(), buffer);
eina_array_push(ea, (void *)eina_stringshare_add(buffer));
if (rand() > RAND_MAX / 2)
{
const char *r = eina_stringshare_add(buffer);
fail_if(r == NULL);
}
}
for (i = 0; i < 10000; ++i)
{
const char *r;
eina_convert_itoa(60000 - i, buffer);
eina_array_push(ea, (void *)eina_stringshare_add(buffer));
r = eina_stringshare_add(buffer);
fail_if(r == NULL);
r = eina_stringshare_add(buffer);
fail_if(r == NULL);
}
for (i = 0; i < 200; ++i)
eina_stringshare_del(eina_array_data_get(ea, i));
for (i = 0; i < 1000; ++i)
eina_stringshare_del(eina_array_pop(ea));
eina_shutdown();
eina_array_free(ea);
}
END_TEST
void
eina_test_stringshare(TCase *tc)
{
tcase_add_test(tc, eina_stringshare_simple);
tcase_add_test(tc, eina_stringshare_small);
tcase_add_test(tc, eina_stringshare_test_share);
tcase_add_test(tc, eina_stringshare_collision);
tcase_add_test(tc, eina_stringshare_putstuff);
}

View File

@ -0,0 +1,184 @@
/* EINA - EFL data type library
* Copyright (C) 2009 Rafael Antognolli
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_suite.h"
#include "Eina.h"
struct test_rect
{
unsigned long col, row;
int x, y, w, h;
Eina_Bool full;
};
static void
check_iterator(Eina_Iterator *it, struct test_rect *cur_test)
{
unsigned int i = 0;
struct Eina_Tile_Grid_Info *tile;
EINA_ITERATOR_FOREACH(it, tile) {
fail_if(cur_test[i].col != tile->col ||
cur_test[i].row != tile->row ||
cur_test[i].x != tile->rect.x ||
cur_test[i].y != tile->rect.y ||
cur_test[i].w != tile->rect.w ||
cur_test[i].h != tile->rect.h ||
cur_test[i].full != tile->full);
i++;
}
fail_if(i == 0);
}
START_TEST(eina_test_tile_grid_slicer_iterator)
{
Eina_Iterator *it;
struct test_rect *cur_test;
struct test_rect test1[] = {{1, 1, 72, 82, 10, 15, 0}};
struct test_rect test2[] =
{{1, 1, 72, 82, 56, 15, 0},
{2, 1, 0, 82, 128, 15, 0},
{3, 1, 0, 82, 116, 15, 0}};
struct test_rect test3[] =
{{1, 1, 72, 82, 10, 46, 0},
{1, 2, 72, 0, 10, 128, 0},
{1, 3, 72, 0, 10, 126, 0}};
struct test_rect test4[] =
{{1, 1, 72, 82, 56, 46, 0},
{2, 1, 0, 82, 128, 46, 0},
{3, 1, 0, 82, 128, 46, 0},
{4, 1, 0, 82, 88, 46, 0},
{1, 2, 72, 0, 56, 128, 0},
{2, 2, 0, 0, 128, 128, 1},
{3, 2, 0, 0, 128, 128, 1},
{4, 2, 0, 0, 88, 128, 0},
{1, 3, 72, 0, 56, 126, 0},
{2, 3, 0, 0, 128, 126, 0},
{3, 3, 0, 0, 128, 126, 0},
{4, 3, 0, 0, 88, 126, 0}};
struct test_rect test5[] = {{1, 1, 0, 0, 128, 128, 1}};
struct test_rect test6[] = {{1, 1, 0, 0, 1, 1, 0}};
struct test_rect test7[] =
{{1, 1, 0, 0, 128, 128, 1},
{2, 1, 0, 0, 1, 128, 0},
{1, 2, 0, 0, 128, 1, 0},
{2, 2, 0, 0, 1, 1, 0}};
eina_init();
cur_test = test1;
it = eina_tile_grid_slicer_iterator_new(200, 210, 10, 15, 128, 128);
check_iterator(it, cur_test);
eina_iterator_free(it);
cur_test = test2;
it = eina_tile_grid_slicer_iterator_new(200, 210, 300, 15, 128, 128);
check_iterator(it, cur_test);
eina_iterator_free(it);
cur_test = test3;
it = eina_tile_grid_slicer_iterator_new(200, 210, 10, 300, 128, 128);
check_iterator(it, cur_test);
eina_iterator_free(it);
cur_test = test4;
it = eina_tile_grid_slicer_iterator_new(200, 210, 400, 300, 128, 128);
check_iterator(it, cur_test);
eina_iterator_free(it);
cur_test = test5;
it = eina_tile_grid_slicer_iterator_new(128, 128, 128, 128, 128, 128);
check_iterator(it, cur_test);
eina_iterator_free(it);
cur_test = test6;
it = eina_tile_grid_slicer_iterator_new(128, 128, 1, 1, 128, 128);
check_iterator(it, cur_test);
eina_iterator_free(it);
cur_test = test7;
it = eina_tile_grid_slicer_iterator_new(128, 128, 129, 129, 128, 128);
check_iterator(it, cur_test);
eina_iterator_free(it);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_tiler_all)
{
Eina_Tiler *tl;
Eina_Iterator *it;
Eina_Rectangle *rp;
Eina_Rectangle r;
int i = 0;
eina_init();
tl = eina_tiler_new(640, 480);
eina_tiler_tile_size_set(tl, 32, 32);
EINA_RECTANGLE_SET(&r, 50, 50, 20, 20);
fail_if(!eina_tiler_rect_add(tl, &r));
EINA_RECTANGLE_SET(&r, -10, -10, 5, 5);
fail_if(eina_tiler_rect_add(tl, &r));
EINA_RECTANGLE_SET(&r, 40, 40, 20, 20);
eina_tiler_rect_del(tl, &r);
it = eina_tiler_iterator_new(tl);
fail_if(!it);
EINA_ITERATOR_FOREACH(it, rp)
{
fail_if(rp->w <= 0);
fail_if(rp->h <= 0);
fail_if(rp->x < 0 || rp->x + rp->w > 640);
fail_if(rp->y < 0 || rp->y + rp->h > 480);
++i;
}
fail_if(eina_iterator_container_get(it) != tl);
eina_iterator_free(it);
fail_if(i == 0);
eina_tiler_clear(tl);
eina_tiler_free(tl);
eina_shutdown();
}
END_TEST
void
eina_test_tiler(TCase *tc)
{
tcase_add_test(tc, eina_test_tile_grid_slicer_iterator);
tcase_add_test(tc, eina_test_tiler_all);
}

View File

@ -0,0 +1,242 @@
/* EINA - EFL data type library
* Copyright (C) 2010 Brett Nash
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "eina_suite.h"
#include "Eina.h"
static const Eina_Unicode STR1[] = {'P', 'a', 'n', 't', 's',' ', 'O', 'n', 0};
static const Eina_Unicode STR2[] = {'P', 'a', 'n', 't', 's',' ', 'O', 'f', 'f', 0};
static const Eina_Unicode STR3[] = {'P', 'a', 'n', 't', 's',' ', 'O', 'n', 0};
static const Eina_Unicode STR4[] = {'A', 0};
static const Eina_Unicode EMPTYSTR[] = {0};
START_TEST(eina_unicode_strcmp_test)
{
eina_init();
/* 1 & 2 */
fail_if(eina_unicode_strcmp(STR1,STR2) == 0);
fail_if(eina_unicode_strcmp(STR1,STR2) < 1);
/* 1 & 3 */
fail_if(eina_unicode_strcmp(STR1, STR3) != 0);
/* 1 & 4 */
fail_if(eina_unicode_strcmp(STR1, STR4) == 0);
fail_if(eina_unicode_strcmp(STR1, STR4) > 1);
/* 1 & empty */
fail_if(eina_unicode_strcmp(STR1, EMPTYSTR) < 1);
/* Self tests */
fail_if(eina_unicode_strcmp(STR1, STR1) != 0);
fail_if(eina_unicode_strcmp(STR2, STR2) != 0);
fail_if(eina_unicode_strcmp(STR3, STR3) != 0);
fail_if(eina_unicode_strcmp(STR4, STR4) != 0);
fail_if(eina_unicode_strcmp(EMPTYSTR, EMPTYSTR) != 0);
eina_shutdown();
}
END_TEST
START_TEST(eina_unicode_strcpy_test)
{
Eina_Unicode buf[10] = { 0 };
Eina_Unicode *rv;
eina_init();
rv = eina_unicode_strcpy(buf,STR1);
fail_if(rv != buf);
fail_if(eina_unicode_strcmp(buf,STR1) != 0);
rv = eina_unicode_strcpy(buf,STR2);
fail_if(rv != buf);
fail_if(eina_unicode_strcmp(buf,STR2) != 0);
/* Now a shorter string */
rv = eina_unicode_strcpy(buf,STR2);
fail_if(rv != buf);
fail_if(eina_unicode_strcmp(buf,STR2) != 0);
/* Really short string */
rv = eina_unicode_strcpy(buf,STR4);
fail_if(rv != buf);
fail_if(eina_unicode_strcmp(buf,STR4) != 0);
fail_if(buf[2] != 'n'); /* check old buf is there */
buf[1] = '7';
rv = eina_unicode_strcpy(buf,EMPTYSTR);
fail_if(rv != buf);
fail_if(buf[0] != 0);
fail_if(buf[1] != '7');
eina_shutdown();
}
END_TEST
START_TEST(eina_unicode_strncpy_test)
{
Eina_Unicode buf[10] = { 0 };
Eina_Unicode *rv;
eina_init();
rv = eina_unicode_strncpy(buf,STR1,9);
fail_if(rv != buf);
fail_if(eina_unicode_strcmp(buf,STR1) != 0);
buf[1] = '7';
rv = eina_unicode_strncpy(buf,STR1,1);
fail_if(rv != buf);
fail_if(buf[1] != '7');
fail_if(buf[0] != STR1[0]);
buf[9] = '7';
rv = eina_unicode_strncpy(buf, STR4, 10);
fail_if(rv != buf);
fail_if(eina_unicode_strcmp(buf,STR4) != 0);
fail_if(buf[9] != 0);
buf[0] = '7';
rv = eina_unicode_strncpy(buf, STR1, 0);
fail_if(buf[0] != '7');
/* may segfault */
buf[0] = '7';
rv = eina_unicode_strncpy(buf, NULL, 0);
fail_if(buf[0] != '7');
/* Hopefully won't segfault */
rv = eina_unicode_strncpy(NULL, STR1, 0);
fail_if(rv != NULL);
eina_shutdown();
}
END_TEST
START_TEST(eina_ustr_strlen_test)
{
eina_init();
fail_if(eina_unicode_strlen(STR1) != 8);
fail_if(eina_unicode_strlen(STR2) != 9);
fail_if(eina_unicode_strlen(STR3) != 8);
fail_if(eina_unicode_strlen(STR4) != 1);
fail_if(eina_unicode_strlen(EMPTYSTR) != 0);
/* Eina unicode doesn't take NULL */
// fail_if(eina_unicode_strlen(NULL));
eina_shutdown();
}
END_TEST
START_TEST(eina_unicode_strnlen_test)
{
eina_init();
/* Strlen style tests*/
fail_if(eina_unicode_strnlen(STR1,10) != 8);
fail_if(eina_unicode_strnlen(STR2,10) != 9);
fail_if(eina_unicode_strnlen(STR3,10) != 8);
fail_if(eina_unicode_strnlen(STR4,10) != 1);
fail_if(eina_unicode_strnlen(EMPTYSTR,10) != 0);
/* Too short tests */
fail_if(eina_unicode_strnlen(STR1,3) != 3);
fail_if(eina_unicode_strnlen(STR2,3) != 3);
fail_if(eina_unicode_strnlen(STR3,3) != 3);
fail_if(eina_unicode_strnlen(EMPTYSTR,1) != 0);
fail_if(eina_unicode_strnlen(NULL,0) != 0);
eina_shutdown();
}
END_TEST
START_TEST(eina_unicode_strdup_test)
{
Eina_Unicode *buf;
eina_init();
buf = eina_unicode_strdup(STR1);
fail_if(!buf);
fail_if(eina_unicode_strlen(buf) != eina_unicode_strlen(STR1));
fail_if(eina_unicode_strcmp(buf, STR1));
free(buf);
buf = eina_unicode_strdup(EMPTYSTR);
fail_if(!buf);
fail_if(buf[0] != 0);
eina_shutdown();
}
END_TEST
START_TEST(eina_unicode_strstr_test)
{
Eina_Unicode *buf;
Eina_Unicode on[] = { 'O', 'n', 0 };
eina_init();
buf = eina_unicode_strstr(STR1,on);
fail_if(!buf);
fail_if(buf != STR1 + 6);
fail_if(eina_unicode_strcmp(buf,on) != 0);
buf = eina_unicode_strstr(STR2,on);
fail_if(buf);
buf = eina_unicode_strstr(EMPTYSTR, on);
fail_if(buf);
buf = eina_unicode_strstr(STR1, EMPTYSTR);
fail_if(!buf);
fail_if(buf != STR1);
eina_shutdown();
}
END_TEST
void
eina_test_ustr(TCase *tc)
{
printf("ustr test\n");
tcase_add_test(tc,eina_unicode_strcmp_test);
tcase_add_test(tc,eina_unicode_strcpy_test);
tcase_add_test(tc,eina_unicode_strncpy_test);
tcase_add_test(tc,eina_ustr_strlen_test);
tcase_add_test(tc,eina_unicode_strnlen_test);
tcase_add_test(tc,eina_unicode_strdup_test);
tcase_add_test(tc,eina_unicode_strstr_test);
}

View File

@ -0,0 +1,119 @@
/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "eina_suite.h"
#include "Eina.h"
static const Eina_Unicode TEST0[] = {'t', 'e', 's', 't', '/', '0', 0};
static const Eina_Unicode TEST1[] = {'t', 'e', 's', 't', '/', '1', 0};
START_TEST(eina_ustringshare_simple)
{
const Eina_Unicode *t0;
const Eina_Unicode *t1;
eina_init();
t0 = eina_ustringshare_add(TEST0);
t1 = eina_ustringshare_add(TEST1);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(eina_unicode_strcmp(t0, TEST0) != 0);
fail_if(eina_unicode_strcmp(t1, TEST1) != 0);
fail_if((int)eina_unicode_strlen(TEST0) != eina_ustringshare_strlen(t0));
fail_if((int)eina_unicode_strlen(TEST1) != eina_ustringshare_strlen(t1));
t0 = eina_ustringshare_ref(t0);
fail_if(t0 == NULL);
fail_if((int)strlen((char*)TEST0) != eina_stringshare_strlen((const char*)t0));
eina_ustringshare_del(t0);
eina_ustringshare_del(t0);
eina_ustringshare_del(t1);
eina_shutdown();
}
END_TEST
START_TEST(eina_ustringshare_test_share)
{
const Eina_Unicode *t0;
const Eina_Unicode *t1;
eina_init();
t0 = eina_ustringshare_add(TEST0);
t1 = eina_ustringshare_add(TEST0);
fail_if(t0 == NULL);
fail_if(t1 == NULL);
fail_if(eina_unicode_strcmp(t0, TEST0) != 0);
fail_if(eina_unicode_strcmp(t1, TEST0) != 0);
fail_if(t0 != t1);
fail_if((int)eina_unicode_strlen(TEST0) != eina_ustringshare_strlen(t0));
fail_if((int)eina_unicode_strlen(TEST0) != eina_ustringshare_strlen(t1));
eina_ustringshare_del(t0);
eina_ustringshare_del(t1);
eina_shutdown();
}
END_TEST
START_TEST(eina_ustringshare_putstuff)
{
const Eina_Unicode *tmp;
int i;
eina_init();
for (i = 10000; i > 0; --i)
{
Eina_Unicode string_[] = {'s', 't', 'r', 'i', 'n', 'g', '_', 0};
Eina_Unicode build[64];
eina_unicode_strcpy(build, string_);
build[7] = i;
build[8] = 0;
tmp = eina_ustringshare_add(build);
fail_if(tmp != eina_ustringshare_add(build));
fail_if((int)eina_unicode_strlen(build) != eina_ustringshare_strlen(tmp));
}
eina_shutdown();
}
END_TEST
void
eina_test_ustringshare(TCase *tc)
{
tcase_add_test(tc, eina_ustringshare_simple);
tcase_add_test(tc, eina_ustringshare_test_share);
tcase_add_test(tc, eina_ustringshare_putstuff);
}

View File

@ -0,0 +1,536 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "Evas_Data.h"
typedef struct _Evas_Hash_El Evas_Hash_El;
struct _Evas_Hash_El
{
Evas_Object_List _list_data;
const char *key;
void *data;
};
static inline int _evas_hash_gen(const char *key);
static int _evas_hash_alloc_error = 0;
static inline int
_evas_hash_gen(const char *key)
{
unsigned int hash_num = 5381;
const unsigned char *ptr;
if (!key)
return 0;
for (ptr = (unsigned char *)key; *ptr; ptr++)
hash_num = (hash_num * 33) ^ *ptr;
hash_num &= 0xff;
return (int)hash_num;
}
/**
* @defgroup Evas_Hash_Data Hash Data Functions
*
* Functions that add, access or remove data from hashes.
*
* The following example shows how to add and then access data in a
* hash table:
* @code
* Evas_Hash *hash = NULL;
* extern void *my_data;
*
* hash = evas_hash_add(hash, "My Data", my_data);
* if (evas_hash_alloc_error())
* {
* fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
* exit(-1);
* }
* if (evas_hash_find(hash, "My Data") == my_data)
* {
* printf("My Data inserted and successfully found.\n");
* }
* @endcode
*
* What follows is another example, showing how the @ref evas_hash_del
* function is used:
* @code
* extern Evas_Hash *hash;
* extern void *data;
*
* printf("Insert some data...\n");
* hash = evas_hash_add(hash, "My Data", my_data);
* printf("Removing by key...\n");
* hash = evas_hash_del(hash, "My Data", NULL);
* printf("Insert some more data as a NULL key...\n");
* hash = evas_hash_add(hash, NULL, my_data);
* printf("Removing by data as a NULL key...\n");
* hash = evas_hash_del(hash, NULL, my_data);
* @endcode
*/
/**
* Adds an entry to the given hash table.
*
* @p key is expected to be a unique string within the hash table.
* Otherwise, you cannot be sure which inserted data pointer will be
* accessed with @ref evas_hash_find , and removed with
* @ref evas_hash_del .
*
* Key strings are case sensitive.
*
* @ref evas_hash_alloc_error should be used to determine if an
* allocation error occurred during this function.
*
* @param hash The given hash table. Can be @c NULL, in which case a
* new hash table is allocated and returned.
* @param key A unique string. Can be @c NULL.
* @param data Data to associate with the string given by @p key.
* @return Either the given hash table, or if the given value for @p
* hash is @c NULL, then a new one. @c NULL will be returned
* if memory could not be allocated for a new table.
* @ingroup Evas_Hash_Data
*/
EAPI Evas_Hash *
evas_hash_add(Evas_Hash *hash, const char *key, const void *data)
{
int hash_num;
Evas_Hash_El *el;
if ((!key) || (!data))
return hash;
_evas_hash_alloc_error = 0;
if (!hash)
{
hash = calloc(1, sizeof(struct _Evas_Hash));
if (!hash)
{
_evas_hash_alloc_error = 1;
return NULL;
}
}
if (!(el = malloc(sizeof(struct _Evas_Hash_El) + strlen(key) + 1)))
{
if (hash->population <= 0)
{
free(hash);
hash = NULL;
}
_evas_hash_alloc_error = 1;
return hash;
}
el->key = ((char *)el) + sizeof(struct _Evas_Hash_El);
strcpy((char *)el->key, key);
el->data = (void *)data;
hash_num = _evas_hash_gen(key);
hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num],
el);
hash->population++;
return hash;
}
/**
* Adds an entry to the given hash table and does not duplicate the string key.
*
* @p key is expected to be a unique string within the hash table.
* Otherwise, you cannot be sure which inserted data pointer will be
* accessed with @ref evas_hash_find , and removed with
* @ref evas_hash_del . This call does not make a copy of the key so it must
* be a string constant or stored elsewhere (in the object being added) etc.
*
* Key strings are case sensitive.
*
* @ref evas_hash_alloc_error should be used to determine if an
* allocation error occurred during this function.
*
* @param hash The given hash table. Can be @c NULL, in which case a
* new hash table is allocated and returned.
* @param key A unique string. Can be @c NULL.
* @param data Data to associate with the string given by @p key.
* @return Either the given hash table, or if the given value for @p
* hash is @c NULL, then a new one. @c NULL will be returned
* if memory could not be allocated for a new table.
* @ingroup Evas_Hash_Data
*/
EAPI Evas_Hash *
evas_hash_direct_add(Evas_Hash *hash, const char *key, const void *data)
{
int hash_num;
Evas_Hash_El *el;
if ((!key) || (!data))
return hash;
_evas_hash_alloc_error = 0;
if (!hash)
{
hash = calloc(1, sizeof(struct _Evas_Hash));
if (!hash)
{
_evas_hash_alloc_error = 1;
return NULL;
}
}
if (!(el = malloc(sizeof(struct _Evas_Hash_El))))
{
if (hash->population <= 0)
{
free(hash);
hash = NULL;
}
_evas_hash_alloc_error = 1;
return hash;
}
el->key = key;
el->data = (void *)data;
hash_num = _evas_hash_gen(key);
hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num],
el);
hash->population++;
return hash;
}
/**
* Removes the entry identified by @p key or @p data from the given
* hash table.
*
* If @p key is @c NULL, then @p data is used to find a match to
* remove.
*
* @param hash The given hash table.
* @param key The key string. Can be @c NULL.
* @param data The data pointer to remove if @p key is @c NULL.
* Otherwise, not required and can be @c NULL.
* @return The modified hash table. If there are no entries left, the
* hash table will be freed and @c NULL will be returned.
* @ingroup Evas_Hash_Data
*/
EAPI Evas_Hash *
evas_hash_del(Evas_Hash *hash, const char *key, const void *data)
{
int hash_num;
Evas_Hash_El *el;
Evas_Object_List *l;
if (!hash)
return NULL;
if (!key)
for (hash_num = 0; hash_num < 256; hash_num++)
{
for (l = hash->buckets[hash_num]; l; l = l->next)
{
el = (Evas_Hash_El *)l;
if (el->data == data)
{
hash->buckets[hash_num] = evas_object_list_remove(
hash->buckets[hash_num],
el);
free(el);
hash->population--;
if (hash->population <= 0)
{
free(hash);
hash = NULL;
}
return hash;
}
}
}
else
{
hash_num = _evas_hash_gen(key);
for (l = hash->buckets[hash_num]; l; l = l->next)
{
el = (Evas_Hash_El *)l;
if (!strcmp(el->key, key))
if ((!data) || (el->data == data))
{
hash->buckets[hash_num] = evas_object_list_remove(
hash->buckets[hash_num],
el);
free(el);
hash->population--;
if (hash->population <= 0)
{
free(hash);
hash = NULL;
}
return hash;
}
}
}
return hash;
}
/**
* Retrieves a specific entry in the given hash table.
* @param hash The given hash table.
* @param key The key string of the entry to find.
* @return The data pointer for the stored entry, or @c NULL if not
* found.
* @ingroup Evas_Hash_Data
*/
EAPI void *
evas_hash_find(const Evas_Hash *hash, const char *key)
{
int hash_num;
Evas_Hash_El *el;
Evas_Object_List *l;
_evas_hash_alloc_error = 0;
if ((!hash) || (!key))
return NULL;
hash_num = _evas_hash_gen(key);
for (l = hash->buckets[hash_num]; l; l = l->next)
{
el = (Evas_Hash_El *)l;
if (!strcmp(el->key, key))
{
if (l != hash->buckets[hash_num])
{
Evas_Object_List *bucket;
bucket = hash->buckets[hash_num];
bucket = evas_object_list_remove(bucket, el);
bucket = evas_object_list_prepend(bucket, el);
((Evas_Hash *)hash)->buckets[hash_num] = bucket;
}
return el->data;
}
}
return NULL;
}
/**
* Modifies the entry pointer at the specified key and returns the old entry
* @param hash The given hash table.
* @param key The key string of the entry to modify.
* @param data The data to replace the old entry, if it exists.
* @return The data pointer for the old stored entry, or @c NULL if not
* found. If an existing entry is not found, nothing is added to the
* hash.
* @ingroup Evas_Hash_Data
*/
EAPI void *
evas_hash_modify(Evas_Hash *hash, const char *key, const void *data)
{
int hash_num;
Evas_Hash_El *el;
Evas_Object_List *l;
_evas_hash_alloc_error = 0;
if (!hash)
return NULL;
hash_num = _evas_hash_gen(key);
for (l = hash->buckets[hash_num]; l; l = l->next)
{
el = (Evas_Hash_El *)l;
if ((key) && (!strcmp(el->key, key)))
{
void *old_data;
if (l != hash->buckets[hash_num])
{
hash->buckets[hash_num] = evas_object_list_remove(
hash->buckets[hash_num],
el);
hash->buckets[hash_num] = evas_object_list_prepend(
hash->buckets[hash_num],
el);
}
old_data = el->data;
el->data = (void *)data;
return old_data;
}
}
return NULL;
}
/**
* @defgroup Evas_Hash_General_Group Hash General Functions
*
* Miscellaneous functions that operate on hash objects.
*/
/**
* Retrieves the number of buckets available in the given hash table.
* @param hash The given hash table.
* @return @c 256 if @p hash is not @c NULL. @c 0 otherwise.
* @ingroup Evas_Hash_General_Group
*/
EAPI int
evas_hash_size(const Evas_Hash *hash)
{
if (!hash)
return 0;
return 256;
}
/**
* @todo Complete polishing documentation for evas_hash.c. The
* functions' docs may be grouped, but they need some simplification.
*/
/**
* Free an entire hash table
* @param hash The hash table to be freed
*
* This function frees up all the memory allocated to storing the specified
* hash tale pointed to by @p hash. Any entries in the table that the program
* has no more pointers for elsewhere may now be lost, so this should only be
* called if the program has lready freed any allocated data in the hash table
* or has the pointers for data in the table stored elswehere as well.
*
* Example:
* @code
* extern Evas_Hash *hash;
*
* evas_hash_free(hash);
* hash = NULL;
* @endcode
* @ingroup Evas_Hash_General_Group
*/
EAPI void
evas_hash_free(Evas_Hash *hash)
{
int i, size;
if (!hash)
return;
size = evas_hash_size(hash);
for (i = 0; i < size; i++)
{
while (hash->buckets[i])
{
Evas_Hash_El *el;
el = (Evas_Hash_El *)hash->buckets[i];
hash->buckets[i] = evas_object_list_remove(hash->buckets[i], el);
free(el);
}
}
free(hash);
}
/**
* Call a function on every member stored in the hash table
* @param hash The hash table whose members will be walked
* @param func The function to call on each parameter
* @param fdata The data pointer to pass to the function being called
*
* This function goes through every entry in the hash table @p hash and calls
* the function @p func on each member. The function should NOT modify the
* hash table contents if it returns 1. IF the hash table contents are
* modified by this function or the function wishes to stop processing it must
* return 0, otherwise return 1 to keep processing.
*
* Example:
* @code
* extern Evas_Hash *hash;
*
* Evas_Bool hash_fn(Evas_Hash *hash, const char *key, void *data, void *fdata)
* {
* printf("Func data: %s, Hash entry: %s / %p\n", fdata, key, data);
* return 1;
* }
*
* int main(int argc, char **argv)
* {
* char *hash_fn_data;
*
* hash_fn_data = strdup("Hello World");
* evas_hash_foreach(hash, hash_fn, hash_fn_data);
* free(hash_fn_data);
* }
* @endcode
* @ingroup Evas_Hash_General_Group
*/
EAPI void
evas_hash_foreach(const Evas_Hash *hash, Evas_Bool (*func)(
const Evas_Hash *hash,
const char *key,
void *data,
void *fdata), const void *fdata)
{
int i, size;
if (!hash)
return;
size = evas_hash_size(hash);
for (i = 0; i < size; i++)
{
Evas_Object_List *l, *next_l;
for (l = hash->buckets[i]; l; )
{
Evas_Hash_El *el;
next_l = l->next;
el = (Evas_Hash_El *)l;
if (!func(hash, el->key, el->data, (void *)fdata))
return;
l = next_l;
}
}
}
/**
* Return memory allocation failure flag after an function requiring allocation
* @return The state of the allocation flag
*
* This function returns the state of the memory allocation flag. This flag is
* set if memory allocations fail during evas_hash_add() calls. If they do, 1
* will be returned, otherwise 0 will be returned. The flag will remain in its
* current state until the next call that requires allocation is called, and
* is then reset.
*
* Example:
* @code
* Evas_Hash *hash = NULL;
* extern void *my_data;
*
* hash = evas_hash_add(hash, "My Data", my_data);
* if (evas_hash_alloc_error())
* {
* fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
* exit(-1);
* }
* if (evas_hash_find(hash, "My Data") == my_data)
* {
* printf("My Data inserted and successfully found.\n");
* }
* @endcode
* @ingroup Evas_Hash_General_Group
*/
EAPI int
evas_hash_alloc_error(void)
{
return _evas_hash_alloc_error;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,200 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "Evas_Data.h"
#include "evas_mempool.h"
//#define NOPOOL
typedef struct _Pool Pool;
struct _Pool
{
int usage;
void *base;
Pool *prev, *next;
};
Pool *
_evas_mp_pool_new(Evas_Mempool *pool)
{
#ifdef NOPOOL
static Pool thepool;
return &thepool;
#else
Pool *p;
void **ptr;
int item_alloc, i;
item_alloc =
((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
p = malloc(sizeof(Pool) + (pool->pool_size * item_alloc));
ptr = (void **)(((unsigned char *)p) + sizeof(Pool));
p->usage = 0;
p->base = ptr;
for (i = 0; i < pool->pool_size - 1; i++)
{
*ptr = (void **)(((unsigned char *)ptr) + item_alloc);
ptr = *ptr;
}
*ptr = NULL;
return p;
#endif
}
void
_evas_mp_pool_free(Pool *p)
{
#if !defined(NOPOOL)
free(p);
#endif
}
void *
evas_mempool_malloc(Evas_Mempool *pool, int size)
{
#ifdef NOPOOL
return malloc(size);
#else
Pool *p;
void *mem;
for (p = pool->first; p; p = p->next) // look 4 pool from 2nd bucket on
{
if (p->base) // base is not NULL - has a free slot
{
if (p->prev)
{
if (pool->last == p)
pool->last = p->prev;
p->prev->next = p->next;
p->prev = NULL;
p->next = pool->first;
p->next->prev = p;
pool->first = p;
}
break;
}
}
if (!p) // we have reached the end of the list - no free pools
{
p = _evas_mp_pool_new(pool);
if (!p)
return NULL;
p->prev = NULL;
p->next = pool->first;
if (p->next)
p->next->prev = p;
if (!pool->last)
pool->last = p;
pool->first = p;
}
mem = p->base; // this points to the next free block - so take it
p->base = *((void **)mem); // base now points to the next free block
if (!p->base) // move to end - it just filled up
if (p->next)
{
if (p->prev)
p->prev->next = p->next;
else
pool->first = p->next;
p->next->prev = p->prev;
((Pool *)pool->last)->next = p;
p->prev = pool->last;
p->next = NULL;
pool->last = p;
}
p->usage++;
pool->usage++;
return mem;
#endif
}
void
evas_mempool_free(Evas_Mempool *pool, void *ptr)
{
#ifdef NOPOOL
free(ptr);
#else
Pool *p;
void *pmem;
int item_alloc, psize;
item_alloc =
((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
psize = item_alloc * pool->pool_size;
for (p = (Pool *)(pool->first); p; p = p->next) // look 4 pool
{
pmem = (void *)(((unsigned char *)p) + sizeof(Pool)); // pool mem base
if ((ptr >= pmem) &&
((unsigned char *)ptr < (((unsigned char *)pmem) + psize))) // is it in pool mem?
{
*((void **)ptr) = p->base; // freed node points to prev free node
p->base = ptr; // next free node is now the one we freed
p->usage--;
pool->usage--;
if (p->usage == 0) // free bucket
{
if (p->prev)
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
if (pool->last == p)
pool->last = p->prev;
if (pool->first == p)
pool->first = p->next;
_evas_mp_pool_free(p);
}
else if (p->prev) // if not the first - move to front
{
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
if (pool->last == p)
pool->last = p->prev;
p->prev = NULL;
p->next = pool->first;
p->next->prev = p;
pool->first = p;
}
break;
}
}
#endif
}
void *
evas_mempool_calloc(Evas_Mempool *pool, int size)
{
#ifdef NOPOOL
return calloc(1, size);
#else
void *mem;
mem = evas_mempool_malloc(pool, size);
memset(mem, 0, size);
return mem;
#endif
}

View File

@ -0,0 +1,21 @@
#ifndef _EVAS_MEMPOOL_H
#define _EVAS_MEMPOOL_H
typedef struct _Evas_Mempool Evas_Mempool;
struct _Evas_Mempool
{
int item_size;
int pool_size;
int usage;
void *first, *last;
};
void *evas_mempool_malloc(Evas_Mempool *pool, int size);
void evas_mempool_free(Evas_Mempool *pool, void *ptr);
void *evas_mempool_calloc(Evas_Mempool *pool, int size);
#endif /* _EVAS_MEMPOOL_H */

View File

@ -0,0 +1,183 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "Evas_Data.h"
/* list ops */
void *
evas_object_list_append(void *in_list, void *in_item)
{
Evas_Object_List *l, *new_l;
Evas_Object_List *list;
list = in_list;
new_l = in_item;
new_l->next = NULL;
if (!list)
{
new_l->prev = NULL;
new_l->last = new_l;
return new_l;
}
if (list->last)
l = list->last;
else
for (l = list; (l) && (l->next); l = l->next) ;
l->next = new_l;
new_l->prev = l;
list->last = new_l;
return list;
}
void *
evas_object_list_prepend(void *in_list, void *in_item)
{
Evas_Object_List *new_l;
Evas_Object_List *list;
list = in_list;
new_l = in_item;
new_l->prev = NULL;
if (!list)
{
new_l->next = NULL;
new_l->last = new_l;
return new_l;
}
new_l->next = list;
list->prev = new_l;
new_l->last = list->last;
list->last = NULL;
return new_l;
}
void *
evas_object_list_append_relative(void *in_list,
void *in_item,
void *in_relative)
{
Evas_Object_List *list, *relative, *new_l;
list = in_list;
new_l = in_item;
relative = in_relative;
if (relative)
{
if (relative->next)
{
new_l->next = relative->next;
relative->next->prev = new_l;
}
else
new_l->next = NULL;
relative->next = new_l;
new_l->prev = relative;
if (!new_l->next)
list->last = new_l;
return list;
}
return evas_object_list_append(list, new_l);
}
void *
evas_object_list_prepend_relative(void *in_list,
void *in_item,
void *in_relative)
{
Evas_Object_List *list, *relative, *new_l;
list = in_list;
new_l = in_item;
relative = in_relative;
if (relative)
{
new_l->prev = relative->prev;
new_l->next = relative;
relative->prev = new_l;
if (new_l->prev)
{
new_l->prev->next = new_l;
if (!new_l->next)
list->last = new_l;
return list;
}
else
{
if (!new_l->next)
new_l->last = new_l;
else
{
new_l->last = list->last;
list->last = NULL;
}
return new_l;
}
}
return evas_object_list_prepend(list, new_l);
}
void *
evas_object_list_remove(void *in_list, void *in_item)
{
Evas_Object_List *return_l;
Evas_Object_List *list, *item;
/* checkme */
if(!in_list)
return in_list;
list = in_list;
item = in_item;
if (!item)
return list;
if (item->next)
item->next->prev = item->prev;
if (item->prev)
{
item->prev->next = item->next;
return_l = list;
}
else
{
return_l = item->next;
if (return_l)
return_l->last = list->last;
}
if (item == list->last)
list->last = item->prev;
item->next = NULL;
item->prev = NULL;
return return_l;
}
void *
evas_object_list_find(void *in_list, void *in_item)
{
Evas_Object_List *l;
Evas_Object_List *list, *item;
list = in_list;
item = in_item;
for (l = list; l; l = l->next)
{
if (l == item)
return item;
}
return NULL;
}

View File

@ -0,0 +1,275 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Evas_Data.h"
typedef struct _Evas_Stringshare Evas_Stringshare;
typedef struct _Evas_Stringshare_El Evas_Stringshare_El;
struct _Evas_Stringshare
{
Evas_Stringshare_El *buckets[1024];
};
struct _Evas_Stringshare_El
{
Evas_Stringshare_El *next;
// int op;
int references;
};
static Evas_Stringshare share =
{
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL
}
};
//static int op = 0;
//static FILE *f = NULL;
static inline int
_evas_stringshare_hash_gen(const char *str, int *len)
{
unsigned int hash_num = 5381;
const unsigned char *ptr;
for (ptr = (const unsigned char *)str; *ptr; ptr++)
{
hash_num = (hash_num * 33) ^ *ptr;
}
hash_num &= 0x3ff;
*len = ptr - (const unsigned char *)str;
return (int)hash_num;
}
EAPI const char *
evas_stringshare_add(const char *str)
{
int hash_num, slen;
char *el_str;
Evas_Stringshare_El *el, *pel = NULL;
if (!str)
{
return NULL; // if (!f)
}
// {
// char bf[256];
// snprintf(bf, sizeof(bf), "strlog-%i", getpid());
// f = fopen(bf, "w");
// }
hash_num = _evas_stringshare_hash_gen(str, &slen);
for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
{
el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
if (!strcmp(el_str, str))
{
if (pel)
{
pel->next = el->next;
el->next = share.buckets[hash_num];
share.buckets[hash_num] = el;
}
el->references++;
// fprintf(f, "strings[%i] = str->add(strings[%i]);\n", el->op, el->op);
// fflush(f);
return el_str;
}
}
if (!(el = malloc(sizeof(Evas_Stringshare_El) + slen + 1)))
return NULL;
el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
strcpy(el_str, str);
el->references = 1;
el->next = share.buckets[hash_num];
share.buckets[hash_num] = el;
// el->op = op;
// fprintf(f, "strings[%i] = str->add(\"%s\");\n", el->op, el_str);
// fflush(f);
// op++;
return el_str;
}
EAPI void
evas_stringshare_del(const char *str)
{
int hash_num, slen;
char *el_str;
Evas_Stringshare_El *el, *pel = NULL;
if (!str)
return;
hash_num = _evas_stringshare_hash_gen(str, &slen);
for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
{
el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
if (el_str == str)
{
el->references--;
// fprintf(f, "str->del(strings[%i]);\n", el->op);
// fflush(f);
if (el->references == 0)
{
if (pel)
pel->next = el->next;
else
share.buckets[hash_num] = el->next;
free(el);
}
else if (pel)
{
pel->next = el->next;
el->next = share.buckets[hash_num];
share.buckets[hash_num] = el;
}
return;
}
}
printf("EEEK trying to del non-shared stringshare \"%s\"\n", str);
abort();
}

46999
legacy/eina/src/tests/strlog Normal file

File diff suppressed because it is too large Load Diff