diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2020-01-02 14:09:50 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2020-01-03 09:43:24 +0100 |
commit | f0b41c5dc29f2715beed7ee93a62de65bcfc26d8 (patch) | |
tree | 30a00ff81896d09679b61776f65b6f2d9147e627 /tests/suite | |
parent | acb025f0d20cda0e2173c822e7d4efa611cce396 (diff) | |
download | gnutls-f0b41c5dc29f2715beed7ee93a62de65bcfc26d8.tar.gz |
ecore cli: updated and rewritten to use libev
That removes a lot of code that was not necessary in the gnutls test
suite.
Resolves: #884
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'tests/suite')
122 files changed, 269 insertions, 44664 deletions
diff --git a/tests/suite/Makefile.am b/tests/suite/Makefile.am index fd8fac7919..5d60d66b54 100644 --- a/tests/suite/Makefile.am +++ b/tests/suite/Makefile.am @@ -27,9 +27,7 @@ AM_CPPFLAGS = \ -I$(top_builddir)/extra/includes \ -I$(top_srcdir)/lib \ -I$(top_srcdir)/tests \ - -I$(top_srcdir)/doc/examples \ - -I$(top_srcdir)/tests/suite/ecore/src/include \ - -I$(top_srcdir)/tests/suite/ecore/src/lib + -I$(top_srcdir)/doc/examples EXTRA_DIST = cbc-record-check.sh @@ -42,49 +40,6 @@ LDADD = ../../lib/libgnutls.la \ prime_check_LDADD = $(LDADD) -lhogweed -lgmp -libecore_la_CPPFLAGS = -I$(top_srcdir)/tests/suite/ecore/ \ - -I$(top_srcdir)/tests/suite/ecore/src/include \ - -I$(top_srcdir)/tests/suite/ecore/src/lib -DHAVE_CONFIG_H \ - -D__UNUSED__= -DVMAJ=1 -D VMIC=0 -DVMIN=0 -DVREV=0 \ - -DEFL_HAVE_POSIX_THREADS=1 -DEFL_HAVE_POSIX_THREADS_SPINLOCK=1 \ - -DEFL_HAVE_THREADS=1 -DEINA_BUILD_CHAINED_POOL=1 \ - -DEINA_STATIC_BUILD_CHAINED_POOL=1 -DHAVE_CLOCK_GETTIME \ - -DHAVE_GETTIMEOFDAY -DPACKAGE_LIB_DIR=\"/usr/lib\" \ - -DMODULE_ARCH=\"unix\" -DSHARED_LIB_SUFFIX=\".so\" - -libecore_la_CFLAGS = -w -nodist_libecore_la_SOURCES = ecore/src/lib/ecore_anim.c \ - ecore/src/lib/ecore_app.c ecore/src/lib/ecore.c \ - ecore/src/lib/ecore_events.c ecore/src/lib/ecore_exe.c \ - ecore/src/lib/ecore_getopt.c ecore/src/lib/ecore_glib.c \ - ecore/src/lib/ecore_idle_enterer.c \ - ecore/src/lib/ecore_idle_exiter.c ecore/src/lib/ecore_idler.c \ - ecore/src/lib/ecore_job.c ecore/src/lib/ecore_main.c \ - ecore/src/lib/ecore_pipe.c ecore/src/lib/ecore_poll.c \ - ecore/src/lib/ecore_signal.c ecore/src/lib/ecore_thread.c \ - ecore/src/lib/ecore_time.c ecore/src/lib/ecore_timer.c \ - ecore/src/lib/eina_accessor.c ecore/src/lib/eina_array.c \ - ecore/src/lib/eina_benchmark.c ecore/src/lib/eina_binshare.c \ - ecore/src/lib/eina_chained_mempool.c \ - ecore/src/lib/eina_convert.c ecore/src/lib/eina_counter.c \ - ecore/src/lib/eina_cpu.c ecore/src/lib/eina_error.c \ - ecore/src/lib/eina_file.c ecore/src/lib/eina_fp.c \ - ecore/src/lib/eina_hamster.c ecore/src/lib/eina_hash.c \ - ecore/src/lib/eina_inlist.c ecore/src/lib/eina_iterator.c \ - ecore/src/lib/eina_lalloc.c ecore/src/lib/eina_list.c \ - ecore/src/lib/eina_log.c ecore/src/lib/eina_magic.c \ - ecore/src/lib/eina_main.c ecore/src/lib/eina_matrixsparse.c \ - ecore/src/lib/eina_mempool.c ecore/src/lib/eina_module.c \ - ecore/src/lib/eina_quadtree.c ecore/src/lib/eina_rbtree.c \ - ecore/src/lib/eina_rectangle.c \ - ecore/src/lib/eina_safety_checks.c ecore/src/lib/eina_sched.c \ - ecore/src/lib/eina_share_common.c ecore/src/lib/eina_strbuf.c \ - ecore/src/lib/eina_strbuf_common.c ecore/src/lib/eina_str.c \ - ecore/src/lib/eina_stringshare.c ecore/src/lib/eina_tiler.c \ - ecore/src/lib/eina_unicode.c ecore/src/lib/eina_ustrbuf.c \ - ecore/src/lib/eina_ustringshare.c ecore/src/lib/eina_value.c - - EXTRA_DIST += testcompat-main-polarssl testcompat-main-openssl \ testcompat-common params.dh tls-fuzzer/tls-fuzzer-common.sh @@ -129,11 +84,9 @@ endif if !MACOSX if !WINDOWS -noinst_LTLIBRARIES = libecore.la - mini_record_timing_LDADD = -lrt $(LDADD) -eagain_cli_LDADD = libecore.la -lrt -lm $(LIBDL) -lpthread $(LDADD) -nodist_eagain_cli_SOURCES = mini-eagain2.c +eagain_cli_LDADD = $(LIBEV_LIBS) -lrt -lm $(LIBDL) -lpthread $(LDADD) +nodist_eagain_cli_SOURCES = eagain-cli.c noinst_PROGRAMS = eagain-cli mini-record-timing @@ -141,6 +94,8 @@ scripts_to_test += eagain.sh endif endif +nodist_prime_check_SOURCES = prime-check.c + nodist_check_SCRIPTS = $(scripts_to_test) TESTS = $(scripts_to_test) prime-check diff --git a/tests/suite/eagain-cli.c b/tests/suite/eagain-cli.c new file mode 100644 index 0000000000..cdd9ab7589 --- /dev/null +++ b/tests/suite/eagain-cli.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2008-2012 Free Software Foundation, Inc. + * Copyright (C) 2018-2020 Red Hat, Inc. + * Copyright (C) 2010 Mike Blumenkrantz + * + * This file is part of GnuTLS. + * + * GnuTLS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <fcntl.h> +#include <netinet/tcp.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "../utils.h" +#include <gnutls/gnutls.h> +#include <assert.h> +#include <sys/time.h> +#include <ev.h> + +static int done = 0; +EV_P; +ev_io remote_w; +gnutls_session_t session; + +static const char +*SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status) +{ + return gnutls_handshake_description_get_name(status); +} + +/* Connects to the peer and returns a socket + * descriptor. + */ +static int tcp_connect(void) +{ + const char *PORT = getenv("PORT"); + const char *SERVER = "127.0.0.1"; //verisign.com + int err, sd; + int flag = 1, curstate = 0; + struct sockaddr_in sa; + + /* sets some fd options such as nonblock */ + sd = socket(AF_INET, SOCK_STREAM, 0); + setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, + sizeof(curstate)); + + + memset(&sa, '\0', sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons(atoi(PORT)); + + inet_pton(AF_INET, SERVER, &sa.sin_addr); + + err = connect(sd, (struct sockaddr *)&sa, sizeof(sa)); + if ((err < 0) && (errno != EINPROGRESS)) { + fprintf(stderr, "Connect error\n"); + exit(1); + } + + /* lower the send buffers to force EAGAIN */ + assert(setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) >= 0); + assert(fcntl(sd, F_SETFL, O_NONBLOCK)>=0); + + return sd; +} + +static void tcp_close(int sd) +{ + shutdown(sd, SHUT_RDWR); /* no more receptions */ + close(sd); +} + +/* We provide this helper to ensure that we test EAGAIN while writing + * even on a reliable connection */ +static ssize_t +_client_push(gnutls_transport_ptr_t tr, const void *data, size_t len) +{ + struct timeval tv; + + assert(gettimeofday(&tv, NULL) >= 0); + + if (tv.tv_usec % 2 == 0) { + errno = EAGAIN; + return -1; + } + + return send((unsigned long)tr, data, len, 0); +} + +static ssize_t +_client_pull(gnutls_transport_ptr_t tr, void *data, size_t len) +{ + struct timeval tv; + + assert(gettimeofday(&tv, NULL) >= 0); + + if (tv.tv_usec % 2 == 0) { + errno = EAGAIN; + return -1; + } + + return recv((unsigned long)tr, data, len, 0); +} + +static int _client_pull_timeout(gnutls_transport_ptr_t ptr, + unsigned int ms) +{ + return gnutls_system_recv_timeout(ptr, ms); +} + +static void _process_data(EV_P_ ev_io * w, int revents) +{ + static int ret = -1, lastret = 0; + static unsigned int count = 0; + static int prev_direction; + + if (!done && (revents & (EV_WRITE|EV_READ))) { + if (lastret == GNUTLS_E_AGAIN) { + if (revents & EV_WRITE) { + assert(prev_direction == 1); + } + if (revents & EV_READ) { + assert(prev_direction == 0); + } + } + + lastret = ret; + ret = gnutls_handshake(session); + count++; + + if (gnutls_record_get_direction(session)) { + ev_io_stop(EV_A_ &remote_w); + ev_io_set(&remote_w, gnutls_transport_get_int(session), EV_WRITE); + ev_io_start(EV_A_ &remote_w); + prev_direction = 1; + } else { + ev_io_stop(EV_A_ &remote_w); + ev_io_set(&remote_w, gnutls_transport_get_int(session), EV_READ); + ev_io_start(EV_A_ &remote_w); + prev_direction = 0; + } + /* avoid printing messages infinity times */ + if (lastret != ret && ret != 0 && ret != GNUTLS_E_AGAIN) { + fprintf(stderr, "gnutls returned with: %s - %s\n", + gnutls_strerror_name(ret), + gnutls_strerror(ret)); + if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) + || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) + fprintf(stderr, "Also received alert: %s\n", + gnutls_alert_get_name + (gnutls_alert_get(session))); + fprintf(stderr, "last out: %s\n", + SSL_GNUTLS_PRINT_HANDSHAKE_STATUS + (gnutls_handshake_get_last_out(session))); + fprintf(stderr, "last in: %s\n", + SSL_GNUTLS_PRINT_HANDSHAKE_STATUS + (gnutls_handshake_get_last_in(session))); + } + + if (gnutls_error_is_fatal(ret)) { + fprintf(stderr, "yarrr this be an error!"); + exit(1); + } + + } + + if (ret == GNUTLS_E_SUCCESS) { + count = 0; + ret = -1; + done = 1; + lastret = 0; + ev_io_stop(EV_A_ & remote_w); + } + + return; +} + +static void try(const char *name, const char *prio) +{ + gnutls_certificate_credentials_t c_certcred; + int sd, i, ret; + + global_init(); + + gnutls_certificate_allocate_credentials(&c_certcred); + + printf("%s: testing priority %s\n", name, prio); + loop = EV_DEFAULT; + + for (i = 0; i < 4; i++) { + done = 0; + + assert(gnutls_init(&session, GNUTLS_CLIENT) >= 0); + gnutls_transport_set_push_function(session, _client_push); + gnutls_transport_set_pull_function(session, _client_pull); + gnutls_transport_set_pull_timeout_function(session, _client_pull_timeout); + gnutls_handshake_set_timeout(session, + GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); + + assert(gnutls_priority_set_direct(session, prio, NULL) >= 0); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, + c_certcred); + gnutls_server_name_set(session, GNUTLS_NAME_DNS, + "localhost", strlen("localhost")); + + sd = tcp_connect(); + + /* associate gnutls with socket */ + gnutls_transport_set_int(session, sd); + + /* add a callback for data being available for send/receive on socket */ + ev_io_init(&remote_w, _process_data, sd, EV_WRITE); + ev_io_start(EV_A_ & remote_w); + + /* begin main loop */ + ev_loop(EV_A_ 0); + + do { + ret = gnutls_bye(session, GNUTLS_SHUT_RDWR); + } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); + + gnutls_deinit(session); + session = NULL; + + tcp_close(sd); + } + + ev_loop_destroy(loop); + gnutls_certificate_free_credentials(c_certcred); + + return; +} + +int main(void) +{ + try("tls 1.2 (dhe)", "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA"); + try("tls 1.2 (rsa)", "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA"); + try("tls 1.3", "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3"); + try("default", "NORMAL"); + return 0; +} diff --git a/tests/suite/eagain.sh b/tests/suite/eagain.sh index cc6668acf1..d012ad8cde 100755 --- a/tests/suite/eagain.sh +++ b/tests/suite/eagain.sh @@ -33,7 +33,10 @@ SERV="${SERV} -q" eval "${GETPORT}" -launch_server $$ --echo --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2:+ANON-DH" --dhparams "${srcdir}/params.dh" +KEY1=${srcdir}/../../doc/credentials/x509/key-rsa.pem +CERT1=${srcdir}/../../doc/credentials/x509/cert-rsa.pem + +launch_server $$ --echo --x509keyfile ${KEY1} --x509certfile ${CERT1} PID=$! wait_server ${PID} diff --git a/tests/suite/ecore/eina_config.h b/tests/suite/ecore/eina_config.h deleted file mode 100644 index 79fa42ca6e..0000000000 --- a/tests/suite/ecore/eina_config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_CONFIG_H_ -#define EINA_CONFIG_H_ - -#ifdef EINA_MAGIC_DEBUG -#undef EINA_MAGIC_DEBUG -#endif -#define EINA_MAGIC_DEBUG - -#ifdef EINA_DEFAULT_MEMPOOL -#undef EINA_DEFAULT_MEMPOOL -#endif - - -#ifdef EINA_SAFETY_CHECKS -#undef EINA_SAFETY_CHECKS -#endif -#define EINA_SAFETY_CHECKS - -#ifdef EINA_HAVE_INTTYPES_H -#undef EINA_HAVE_INTTYPES_H -#endif -#define EINA_HAVE_INTTYPES_H - -#ifdef EINA_HAVE_STDINT_H -#undef EINA_HAVE_STDINT_H -#endif -#define EINA_HAVE_STDINT_H - -#ifdef EINA_SIZEOF_WCHAR_T -#undef EINA_SIZEOF_WCHAR_T -#endif -#define EINA_SIZEOF_WCHAR_T 4 - -#endif /* EINA_CONFIG_H_ */ diff --git a/tests/suite/ecore/src/include/Eina.h b/tests/suite/ecore/src/include/Eina.h deleted file mode 100644 index cbb13f5a76..0000000000 --- a/tests/suite/ecore/src/include/Eina.h +++ /dev/null @@ -1,164 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008-2010 Enlightenment Developers: - * Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com> - * Alexandre "diaxen" Becoulet <diaxen@free.fr> - * Andre Dieb <andre.dieb@gmail.com> - * Arnaud de Turckheim "quarium" <quarium@gmail.com> - * Carsten Haitzler <raster@rasterman.com> - * Cedric Bail <cedric.bail@free.fr> - * Corey "atmos" Donohoe <atmos@atmos.org> - * Fabiano Fidêncio <fidencio@profusion.mobi> - * Gustavo Chaves <glima@profusion.mobi> - * Gustavo Sverzut Barbieri <barbieri@gmail.com> - * Jorge Luis "turran" Zapata <jorgeluis.zapata@gmail.com> - * Peter "pfritz" Wehrfritz <peter.wehrfritz@web.de> - * Raphael Kubo da Costa <kubo@profusion.mobi> - * Tilman Sauerbeck <tilman@code-monkey.de> - * Vincent "caro" Torri <vtorri at univ-evry dot fr> - * Tom Hacohen <tom@stosb.com> - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_H_ -#define EINA_H_ - -/** - * @mainpage Eina - * - * @author Albin "Lutin" Tonnerre <albin.tonnerre@@gmail.com> - * @author Alexandre "diaxen" Becoulet <diaxen@@free.fr> - * @author Andre Dieb <andre.dieb@@gmail.com> - * @author Arnaud de Turckheim "quarium" <quarium@@gmail.com> - * @author Carsten Haitzler <raster@@rasterman.com> - * @author Cedric Bail <cedric.bail@@free.fr> - * @author Corey "atmos" Donohoe <atmos@@atmos.org> - * @author Fabiano Fidêncio <fidencio@@profusion.mobi> - * @author Gustavo Chaves <glima@@profusion.mobi> - * @author Gustavo Sverzut Barbieri <barbieri@@profusion.mobi> - * @author Jorge Luis "turran" Zapata <jorgeluis.zapata@@gmail.com> - * @author Peter "pfritz" Wehrfritz <peter.wehrfritz@@web.de> - * @author Raphael Kubo da Costa <kubo@@profusion.mobi> - * @author Tilman Sauerbeck <tilman@@code-monkey.de> - * @author Vincent "caro" Torri <vtorri at univ-evry dot fr> - * @author Tom Hacohen <tom@@stosb.com> - * @date 2008-2010 - * - * @section eina_intro_sec Introduction - * - * The Eina library is a library that implements an API for data types - * in an efficient way. It also provides some useful tools like - * openin shared libraries, errors management, type conversion, - * time accounting and memory pool. - * - * This library is cross-platform and can be compiled and used on - * Linux, BSD, Opensolaris and Windows (XP and CE). - * - * The data types that are available are (see @ref Eina_Data_Types_Group): - * @li @ref Eina_Array_Group standard array of @c void* data. - * @li @ref Eina_Hash_Group standard hash of @c void* data. - * @li @ref Eina_Inline_List_Group list with nodes inlined into user type. - * @li @ref Eina_List_Group standard list of @c void* data. - * @li @ref Eina_Matrixsparse_Group sparse matrix of @c void* data. - * @li @ref Eina_Rbtree_Group red-black tree with nodes inlined into user type. - * @li @ref Eina_String_Buffer_Group mutable string to prepend, insert or append strings to a buffer. - * @li @ref Eina_Stringshare_Group saves memory by sharing read-only string references. - * @li @ref Eina_Tiler_Group split, merge and navigates into 2D tiled regions. - * @li @ref Eina_Trash_Group container of unused but allocated data. - * - * The tools that are available are (see @ref Eina_Tools_Group): - * @li @ref Eina_Benchmark_Group helper to write benchmarks. - * @li @ref Eina_Convert_Group faster conversion from strings to integers, double, etc. - * @li @ref Eina_Counter_Group measures number of calls and their time. - * @li @ref Eina_Error_Group error identifiers. - * @li @ref Eina_File_Group simple file list and path split. - * @li @ref Eina_Lalloc_Group simple lazy allocator. - * @li @ref Eina_Log_Group full-featured logging system. - * @li @ref Eina_Magic_Group provides runtime type checking. - * @li @ref Eina_Memory_Pool_Group abstraction for various memory allocators. - * @li @ref Eina_Module_Group lists, loads and share modules using Eina_Module standard. - * @li @ref Eina_Rectangle_Group rectangle structure and standard manipulation methods. - * @li @ref Eina_Safety_Checks_Group extra checks that will report unexpected conditions and can be disabled at compile time. - * @li @ref Eina_String_Group a set of functions that manages C strings. - * - * @defgroup Eina_Data_Types_Group Data types. - * - * Eina provide easy to use and optimized data types and structures. - * - * - * @defgroup Eina_Containers_Group Containers - * - * Containers are data types that hold data and allow iteration over - * their elements with an @ref Eina_Iterator_Group, or eventually an - * @ref Eina_Accessor_Group. - * - * - * @defgroup Eina_Tools_Group Tools - * - * Eina tools aims to help application development, providing ways to - * make it safer, log errors, manage memory more efficiently and more. - */ - -#include <dirent.h> - -#ifdef _WIN32 -#include <Evil.h> -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "eina_config.h" -#include "eina_types.h" -#include "eina_main.h" -#include "eina_fp.h" -#include "eina_rectangle.h" -#include "eina_inlist.h" -#include "eina_file.h" -#include "eina_list.h" -#include "eina_hash.h" -#include "eina_trash.h" -#include "eina_lalloc.h" -#include "eina_module.h" -#include "eina_mempool.h" -#include "eina_error.h" -#include "eina_log.h" -#include "eina_array.h" -#include "eina_binshare.h" -#include "eina_stringshare.h" -#include "eina_ustringshare.h" -#include "eina_magic.h" -#include "eina_counter.h" -#include "eina_rbtree.h" -#include "eina_accessor.h" -#include "eina_iterator.h" -#include "eina_benchmark.h" -#include "eina_convert.h" -#include "eina_cpu.h" -#include "eina_sched.h" -#include "eina_tiler.h" -#include "eina_hamster.h" -#include "eina_matrixsparse.h" -#include "eina_str.h" -#include "eina_strbuf.h" -#include "eina_ustrbuf.h" -#include "eina_unicode.h" -#include "eina_quadtree.h" - -#ifdef __cplusplus -} -#endif -#endif /* EINA_H */ diff --git a/tests/suite/ecore/src/include/eina_accessor.h b/tests/suite/ecore/src/include/eina_accessor.h deleted file mode 100644 index a5a5bdab5f..0000000000 --- a/tests/suite/ecore/src/include/eina_accessor.h +++ /dev/null @@ -1,151 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_ACCESSOR_H__ -#define EINA_ACCESSOR_H__ - -#include "eina_config.h" - -#include "eina_types.h" -#include "eina_magic.h" - -/** - * @addtogroup Eina_Content_Access_Group Content Access - * - * @{ - */ - -/** - * @defgroup Eina_Accessor_Group Accessor Functions - * - * @{ - */ - -/** - * @typedef Eina_Accessor - * Type for accessors. - */ -typedef struct _Eina_Accessor Eina_Accessor; - -typedef Eina_Bool(*Eina_Accessor_Get_At_Callback) (Eina_Accessor * it, - unsigned int index, - void **data); -typedef void *(*Eina_Accessor_Get_Container_Callback) (Eina_Accessor * it); -typedef void (*Eina_Accessor_Free_Callback) (Eina_Accessor * it); -typedef Eina_Bool(*Eina_Accessor_Lock_Callback) (Eina_Accessor * it); - -struct _Eina_Accessor { -#define EINA_ACCESSOR_VERSION 1 - int version; - - Eina_Accessor_Get_At_Callback get_at EINA_ARG_NONNULL(1, - 3) - EINA_WARN_UNUSED_RESULT; - Eina_Accessor_Get_Container_Callback get_container - EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; - Eina_Accessor_Free_Callback free EINA_ARG_NONNULL(1); - - Eina_Accessor_Lock_Callback lock EINA_WARN_UNUSED_RESULT; - Eina_Accessor_Lock_Callback unlock EINA_WARN_UNUSED_RESULT; - -#define EINA_MAGIC_ACCESSOR 0x98761232 - EINA_MAGIC}; - -#define FUNC_ACCESSOR_GET_AT(Function) ((Eina_Accessor_Get_At_Callback)Function) -#define FUNC_ACCESSOR_GET_CONTAINER(Function) ((Eina_Accessor_Get_Container_Callback)Function) -#define FUNC_ACCESSOR_FREE(Function) ((Eina_Accessor_Free_Callback)Function) -#define FUNC_ACCESSOR_LOCK(Function) ((Eina_Accessor_Lock_Callback)Function) - -EAPI void eina_accessor_free(Eina_Accessor * accessor) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_accessor_data_get(Eina_Accessor * accessor, - unsigned int position, - void **data) EINA_ARG_NONNULL(1); -EAPI void *eina_accessor_container_get(Eina_Accessor * - accessor) EINA_ARG_NONNULL(1) - EINA_PURE; -EAPI void eina_accessor_over(Eina_Accessor * accessor, Eina_Each_Cb cb, - unsigned int start, unsigned int end, - const void *fdata) EINA_ARG_NONNULL(1, 2); -EAPI Eina_Bool eina_accessor_lock(Eina_Accessor * - accessor) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_accessor_unlock(Eina_Accessor * - accessor) EINA_ARG_NONNULL(1); - -/** - * @def EINA_ACCESSOR_FOREACH - * @brief Macro to iterate over all elements easily. - * - * @param accessor The accessor to use. - * @param counter A counter used by eina_accessor_data_get() when - * iterating over the container. - * @param data Where to store * data, must be a pointer support getting - * its address since * eina_accessor_data_get() requires a pointer to - * pointer! - * - * This macro allows a convenient way to loop over all elements in an - * accessor, very similar to EINA_LIST_FOREACH(). - * - * This macro can be used for freeing the data of a list, like in the - * following example. It has the same goal as the one documented in - * EINA_LIST_FOREACH(), but using accessors: - * - * @code - * Eina_List *list; - * Eina_Accessor *accessor; - * unsigned int i; - * char *data; - * - * // list is already filled, - * // its elements are just duplicated strings - * - * accessor = eina_list_accessor_new(list); - * EINA_ACCESSOR_FOREACH(accessor, i, data) - * free(data); - * eina_accessor_free(accessor); - * eina_list_free(list); - * @endcode - * - * @note if the datatype provides both iterators and accessors prefer - * to use iterators to iterate over, as they're likely to be more - * optimized for such task. - * - * @note this example is not optimal algorithm to release a list since - * it will walk the list twice, but it serves as an example. For - * optimized version use EINA_LIST_FREE() - * - * @warning unless explicitly stated in functions returning accessors, - * do not modify the accessed object while you walk it, in this - * example using lists, do not remove list nodes or you might - * crash! This is not a limitiation of accessors themselves, - * rather in the accessors implementations to keep them as simple - * and fast as possible. - */ -#define EINA_ACCESSOR_FOREACH(accessor, counter, data) \ - for ((counter) = 0; \ - eina_accessor_data_get((accessor), (counter), (void **)&(data)); \ - (counter)++) - -/** - * @} - */ - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_array.h b/tests/suite/ecore/src/include/eina_array.h deleted file mode 100644 index e156ce5b72..0000000000 --- a/tests/suite/ecore/src/include/eina_array.h +++ /dev/null @@ -1,163 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_ARRAY_H_ -#define EINA_ARRAY_H_ - -#include <stdlib.h> - -#include "eina_config.h" - -#include "eina_types.h" -#include "eina_error.h" -#include "eina_iterator.h" -#include "eina_accessor.h" -#include "eina_magic.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_Array_Group Array - * - * @{ - */ - -/** - * @typedef Eina_Array - * Type for a generic vector. - */ -typedef struct _Eina_Array Eina_Array; - -/** - * @typedef Eina_Array_Iterator - * Type for an iterator on arrays, used with #EINA_ARRAY_ITER_NEXT. - */ -typedef void **Eina_Array_Iterator; - -/** - * @struct _Eina_Array - * Type for an array of data. - */ -struct _Eina_Array { -#define EINA_ARRAY_VERSION 1 - int version; - /**< Should match EINA_ARRAY_VERSION used when compiled your apps, provided for ABI compatibility */ - - void **data; - /**< Pointer to a vector of pointer to payload */ - unsigned int total; - /**< Total number of slots in the vector */ - unsigned int count; - /**< Number of active slots in the vector */ - unsigned int step; - /**< How much must we grow the vector when it is full */ - EINA_MAGIC}; - -EAPI Eina_Array *eina_array_new(unsigned int step) -EINA_WARN_UNUSED_RESULT EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI void eina_array_free(Eina_Array * array) EINA_ARG_NONNULL(1); -EAPI void eina_array_step_set(Eina_Array * array, - unsigned int sizeof_eina_array, - unsigned int step) EINA_ARG_NONNULL(1); -EAPI void eina_array_clean(Eina_Array * array) EINA_ARG_NONNULL(1); -EAPI void eina_array_flush(Eina_Array * array) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_array_remove(Eina_Array * array, - Eina_Bool(*keep) (void *data, - void *gdata), - void *gdata) EINA_ARG_NONNULL(1, 2); -static inline Eina_Bool eina_array_push(Eina_Array * array, - const void *data) -EINA_ARG_NONNULL(1, 2); -static inline void *eina_array_pop(Eina_Array * array) EINA_ARG_NONNULL(1); -static inline void *eina_array_data_get(const Eina_Array * array, - unsigned int idx) -EINA_ARG_NONNULL(1); -static inline void eina_array_data_set(const Eina_Array * array, - unsigned int idx, - const void *data) -EINA_ARG_NONNULL(1, 3); -static inline unsigned int eina_array_count_get(const Eina_Array * - array) EINA_ARG_NONNULL(1); -EAPI Eina_Iterator *eina_array_iterator_new(const Eina_Array * array) -EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Accessor *eina_array_accessor_new(const Eina_Array * array) -EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -static inline Eina_Bool eina_array_foreach(Eina_Array * array, - Eina_Each_Cb cb, void *data); -/** - * @def EINA_ARRAY_ITER_NEXT - * @brief Macro to iterate over an array easily. - * - * @param array The array to iterate over. - * @param index The integer number that is increased while itareting. - * @param item The data - * @param iterator The iterator - * - * This macro allows the iteration over @p array in an easy way. It - * iterates from the first element to the last one. @p index is an - * integer that increases from 0 to the number of elements. @p item is - * the data of each element of @p array, so it is a pointer to a type - * chosen by the user. @p iterator is of type #Eina_Array_Iterator. - * - * This macro can be used for freeing the data of an array, like in - * the following example: - * - * @code - * Eina_Array *array; - * char *item; - * Eina_Array_Iterator iterator; - * unsigned int i; - * - * // array is already filled, - * // its elements are just duplicated strings, - * // EINA_ARRAY_ITER_NEXT will be used to free those strings - * - * EINA_ARRAY_ITER_NEXT(array, i, item, iterator) - * free(item); - * @endcode - */ -#define EINA_ARRAY_ITER_NEXT(array, index, item, iterator) \ - for (index = 0, iterator = (array)->data; \ - (index < eina_array_count_get(array)) && ((item = *((iterator)++))); \ - ++(index)) - -#include "eina_inline_array.x" - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_benchmark.h b/tests/suite/ecore/src/include/eina_benchmark.h deleted file mode 100644 index 3c7af673b9..0000000000 --- a/tests/suite/ecore/src/include/eina_benchmark.h +++ /dev/null @@ -1,75 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_BENCHMARK_H_ -#define EINA_BENCHMARK_H_ - -#include "eina_array.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Benchmark_Group Benchmark - * - * @{ - */ - -/** - * @typedef Eina_Benchmark - * Type for a benchmark. - */ -typedef struct _Eina_Benchmark Eina_Benchmark; - -/** - * @typedef Eina_Benchmark_Specimens - * Type for a test function to be called when running a benchmark. - */ -typedef void (*Eina_Benchmark_Specimens) (int request); - -/** - * @def EINA_BENCHMARK - * @brief cast to an #Eina_Benchmark_Specimens. - * - * @param function The function to cast. - * - * This macro casts @p function to Eina_Benchmark_Specimens. - */ -#define EINA_BENCHMARK(function) ((Eina_Benchmark_Specimens)function) - -EAPI Eina_Benchmark *eina_benchmark_new(const char *name, const char *run); -EAPI void eina_benchmark_free(Eina_Benchmark * bench); -EAPI Eina_Bool eina_benchmark_register(Eina_Benchmark * bench, - const char *name, - Eina_Benchmark_Specimens bench_cb, - int count_start, - int count_end, int count_set); -EAPI Eina_Array *eina_benchmark_run(Eina_Benchmark * bench); - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_BENCHMARK_H_ */ diff --git a/tests/suite/ecore/src/include/eina_binshare.h b/tests/suite/ecore/src/include/eina_binshare.h deleted file mode 100644 index 05b563d88d..0000000000 --- a/tests/suite/ecore/src/include/eina_binshare.h +++ /dev/null @@ -1,106 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (C) 2008 Peter Wehrfritz - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies of the Software and its Copyright notices. In addition publicly - * documented acknowledgment must be given that this software has been used if no - * source code of this software is made available publicly. This includes - * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing - * documents or any documentation provided with any product containing this - * software. This License does not apply to any software that links to the - * libraries provided by this software (statically or dynamically), but only to - * the software provided. - * - * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice - * and it's intent. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef EINA_BINSHARE_H_ -#define EINA_BINSHARE_H_ - -#include "eina_types.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @defgroup Eina_Binshare_Group Binary Share - * - * @{ - */ - -EAPI Eina_Bool eina_binshare_init(void); -EAPI Eina_Bool eina_binshare_shutdown(void); -EAPI const void *eina_binshare_add_length(const void *obj, - unsigned int olen) -EINA_PURE EINA_WARN_UNUSED_RESULT; -EAPI const void *eina_binshare_ref(const void *obj); -EAPI void eina_binshare_del(const void *obj); -EAPI int eina_binshare_length(const void *obj) EINA_WARN_UNUSED_RESULT; -EAPI void eina_binshare_dump(void); - -/** - * @brief Retrieve an instance of a blob for use in a program. - * - * @param ptr The binary blob to retrieve an instance of. - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This macro retrieves an instance of @p obj. If @p obj is - * @c NULL, then @c NULL is returned. If @p obj is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the blobs to be searched and a duplicated blob - * of @p obj is returned. - * - * This macro essentially calls eina_binshare_add_length with ptr and sizeof(*ptr) - * as the parameters. It's useful for pointers to structures. - * - * @see eina_stringshare_add_length() - */ -#define eina_binshare_add(ptr) eina_binshare_add_length(ptr, sizeof(*ptr)) - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_STRINGSHARE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_config.h b/tests/suite/ecore/src/include/eina_config.h deleted file mode 100644 index 79fa42ca6e..0000000000 --- a/tests/suite/ecore/src/include/eina_config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_CONFIG_H_ -#define EINA_CONFIG_H_ - -#ifdef EINA_MAGIC_DEBUG -#undef EINA_MAGIC_DEBUG -#endif -#define EINA_MAGIC_DEBUG - -#ifdef EINA_DEFAULT_MEMPOOL -#undef EINA_DEFAULT_MEMPOOL -#endif - - -#ifdef EINA_SAFETY_CHECKS -#undef EINA_SAFETY_CHECKS -#endif -#define EINA_SAFETY_CHECKS - -#ifdef EINA_HAVE_INTTYPES_H -#undef EINA_HAVE_INTTYPES_H -#endif -#define EINA_HAVE_INTTYPES_H - -#ifdef EINA_HAVE_STDINT_H -#undef EINA_HAVE_STDINT_H -#endif -#define EINA_HAVE_STDINT_H - -#ifdef EINA_SIZEOF_WCHAR_T -#undef EINA_SIZEOF_WCHAR_T -#endif -#define EINA_SIZEOF_WCHAR_T 4 - -#endif /* EINA_CONFIG_H_ */ diff --git a/tests/suite/ecore/src/include/eina_convert.h b/tests/suite/ecore/src/include/eina_convert.h deleted file mode 100644 index efbb77558c..0000000000 --- a/tests/suite/ecore/src/include/eina_convert.h +++ /dev/null @@ -1,79 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008 Cedric BAIL, Vincent Torri - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_CONVERT_H_ -#define EINA_CONVERT_H_ - -#include "eina_types.h" -#include "eina_error.h" - -#include "eina_fp.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Convert_Group Convert - * - * @{ - */ - -/** - * @var EINA_ERROR_CONVERT_P_NOT_FOUND - * Error identifier corresponding to string not containing 'p'. - */ -EAPI extern Eina_Error EINA_ERROR_CONVERT_P_NOT_FOUND; - -/** - * @var EINA_ERROR_CONVERT_0X_NOT_FOUND - * Error identifier corresponding to string not containing '0x'. - */ -EAPI extern Eina_Error EINA_ERROR_CONVERT_0X_NOT_FOUND; - -/** - * @var EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH - * Error identifier corresponding to length of the string being too small. - */ -EAPI extern Eina_Error EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH; - -EAPI int eina_convert_itoa(int n, char *s) EINA_ARG_NONNULL(2); -EAPI int eina_convert_xtoa(unsigned int n, char *s) EINA_ARG_NONNULL(2); - -EAPI int eina_convert_dtoa(double d, char *des) EINA_ARG_NONNULL(2); -EAPI Eina_Bool eina_convert_atod(const char *src, - int length, - long long *m, - long *e) EINA_ARG_NONNULL(1, 3, 4); - -EAPI int eina_convert_fptoa(Eina_F32p32 fp, char *des) EINA_ARG_NONNULL(2); -EAPI Eina_Bool eina_convert_atofp(const char *src, - int length, - Eina_F32p32 * fp) EINA_ARG_NONNULL(1, 3); - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_CONVERT_H_ */ diff --git a/tests/suite/ecore/src/include/eina_counter.h b/tests/suite/ecore/src/include/eina_counter.h deleted file mode 100644 index 7743ba6be2..0000000000 --- a/tests/suite/ecore/src/include/eina_counter.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_COUNTER_H_ -#define EINA_COUNTER_H_ - -#include "eina_types.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Counter_Group Counter - * - * @{ - */ - -/** - * @typedef Eina_Counter - * Counter type. - */ -typedef struct _Eina_Counter Eina_Counter; - -EAPI Eina_Counter *eina_counter_new(const char *name) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); -EAPI void eina_counter_free(Eina_Counter * counter) EINA_ARG_NONNULL(1); -EAPI void eina_counter_start(Eina_Counter * counter) EINA_ARG_NONNULL(1); -EAPI void eina_counter_stop(Eina_Counter * counter, - int specimen) EINA_ARG_NONNULL(1); -EAPI char *eina_counter_dump(Eina_Counter * counter) EINA_ARG_NONNULL(1); - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_COUNTER_H_ */ diff --git a/tests/suite/ecore/src/include/eina_cpu.h b/tests/suite/ecore/src/include/eina_cpu.h deleted file mode 100644 index f87c308839..0000000000 --- a/tests/suite/ecore/src/include/eina_cpu.h +++ /dev/null @@ -1,38 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_CPU_H_ -#define EINA_CPU_H_ - -#include "eina_types.h" - -typedef enum _Eina_Cpu_Features { - EINA_CPU_MMX = 0x00000001, - EINA_CPU_SSE = 0x00000002, - EINA_CPU_SSE2 = 0x00000004, - EINA_CPU_SSE3 = 0x00000008, - /* TODO 3DNow! */ - EINA_CPU_ALTIVEC = 0x00000010, - EINA_CPU_VIS = 0x00000020, - EINA_CPU_NEON = 0x00000040, -} Eina_Cpu_Features; - -EAPI Eina_Cpu_Features eina_cpu_features_get(void); -EAPI int eina_cpu_count(void); - -#endif /* EINA_CPU_H_ */ diff --git a/tests/suite/ecore/src/include/eina_error.h b/tests/suite/ecore/src/include/eina_error.h deleted file mode 100644 index 71b3ea5da3..0000000000 --- a/tests/suite/ecore/src/include/eina_error.h +++ /dev/null @@ -1,68 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_ERROR_H_ -#define EINA_ERROR_H_ - -#include <stdarg.h> - -#include "eina_types.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Error_Group Error - * - * @{ - */ - -/** - * @typedef Eina_Error - * Error type. - */ -typedef int Eina_Error; - -/** - * @var EINA_ERROR_OUT_OF_MEMORY - * Error identifier corresponding to a lack of memory. - */ -EAPI extern Eina_Error EINA_ERROR_OUT_OF_MEMORY; - -EAPI Eina_Error eina_error_msg_register(const char *msg) -EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Error eina_error_msg_static_register(const char *msg) -EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Bool eina_error_msg_modify(Eina_Error error, - const char *msg) EINA_ARG_NONNULL(2); -EAPI Eina_Error eina_error_get(void); -EAPI void eina_error_set(Eina_Error err); -EAPI const char *eina_error_msg_get(Eina_Error error) EINA_PURE; - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_ERROR_H_ */ diff --git a/tests/suite/ecore/src/include/eina_file.h b/tests/suite/ecore/src/include/eina_file.h deleted file mode 100644 index e7ea6d00eb..0000000000 --- a/tests/suite/ecore/src/include/eina_file.h +++ /dev/null @@ -1,104 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_FILE_H_ -#define EINA_FILE_H_ - -#include <limits.h> - -#include "eina_types.h" -#include "eina_array.h" -#include "eina_iterator.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_File_Group File - * - * @{ - */ - -/** - * @typedef Eina_File_Direct_Info - * A typedef to #_Eina_File_Direct_Info. - */ -typedef struct _Eina_File_Direct_Info Eina_File_Direct_Info; - -/** - * @typedef Eina_File_Dir_List_Cb - * Type for a callback to be called when iterating over the files of a - * directory. - */ -typedef void (*Eina_File_Dir_List_Cb) (const char *name, const char *path, - void *data); - -#ifndef _POSIX_PATH_MAX -# define _POSIX_PATH_MAX 256 -#endif - -/** - * @struct _Eina_File_Direct_Info - * A structure to store informations of a path. - */ -struct _Eina_File_Direct_Info { - size_t path_length; - /**< size of the whole path */ - size_t name_length; - /**< size of the filename/basename component */ - size_t name_start; - /**< where the filename/basename component starts */ - char path[_POSIX_PATH_MAX]; - /**< the path */ - const struct dirent *dirent; - /**< the dirent structure of the path */ -}; - -/** - * @def EINA_FILE_DIR_LIST_CB - * @brief cast to an #Eina_File_Dir_List_Cb. - * - * @param function The function to cast. - * - * This macro casts @p function to Eina_File_Dir_List_Cb. - */ -#define EINA_FILE_DIR_LIST_CB(function) ((Eina_File_Dir_List_Cb)function) - -EAPI Eina_Bool eina_file_dir_list(const char *dir, - Eina_Bool recursive, - Eina_File_Dir_List_Cb cb, - void *data) EINA_ARG_NONNULL(1, 3); -EAPI Eina_Array *eina_file_split(char *path) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; -EAPI Eina_Iterator *eina_file_ls(const char *dir) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; -EAPI Eina_Iterator *eina_file_direct_ls(const char *dir) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_FILE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_fp.h b/tests/suite/ecore/src/include/eina_fp.h deleted file mode 100644 index e1b5f16b10..0000000000 --- a/tests/suite/ecore/src/include/eina_fp.h +++ /dev/null @@ -1,96 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * Copyright (C) 2009 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_FP_H_ -#define EINA_FP_H_ - -#include "eina_types.h" - -#ifdef _MSC_VER -typedef unsigned __int64 uint64_t; -typedef signed __int64 int64_t; -typedef signed int int32_t; -#else -#include <stdint.h> -#endif - -#define EINA_F32P32_PI 0x00000003243f6a89 - -typedef int64_t Eina_F32p32; -typedef int32_t Eina_F16p16; -typedef int32_t Eina_F8p24; - -static inline Eina_F32p32 eina_f32p32_int_from(int32_t v); -static inline int32_t eina_f32p32_int_to(Eina_F32p32 v); -static inline Eina_F32p32 eina_f32p32_double_from(double v); -static inline double eina_f32p32_double_to(Eina_F32p32 v); - -static inline Eina_F32p32 eina_f32p32_add(Eina_F32p32 a, Eina_F32p32 b); -static inline Eina_F32p32 eina_f32p32_sub(Eina_F32p32 a, Eina_F32p32 b); -static inline Eina_F32p32 eina_f32p32_mul(Eina_F32p32 a, Eina_F32p32 b); -static inline Eina_F32p32 eina_f32p32_scale(Eina_F32p32 a, int b); -static inline Eina_F32p32 eina_f32p32_div(Eina_F32p32 a, Eina_F32p32 b); -static inline Eina_F32p32 eina_f32p32_sqrt(Eina_F32p32 a); -static inline unsigned int eina_f32p32_fracc_get(Eina_F32p32 v); - -// dont use llabs - issues if not on 64bit -#define eina_fp32p32_llabs(a) ((a < 0) ? -(a) : (a)) - -EAPI Eina_F32p32 eina_f32p32_cos(Eina_F32p32 a); -EAPI Eina_F32p32 eina_f32p32_sin(Eina_F32p32 a); - -static inline Eina_F16p16 eina_f16p16_int_from(int32_t v); -static inline int32_t eina_f16p16_int_to(Eina_F16p16 v); -static inline Eina_F16p16 eina_f16p16_float_from(float v); -static inline float eina_f16p16_float_to(Eina_F16p16 v); - -static inline Eina_F16p16 eina_f16p16_add(Eina_F16p16 a, Eina_F16p16 b); -static inline Eina_F16p16 eina_f16p16_sub(Eina_F16p16 a, Eina_F16p16 b); -static inline Eina_F16p16 eina_f16p16_mul(Eina_F16p16 a, Eina_F16p16 b); -static inline Eina_F16p16 eina_f16p16_scale(Eina_F16p16 a, int b); -static inline Eina_F16p16 eina_f16p16_div(Eina_F16p16 a, Eina_F16p16 b); -static inline Eina_F16p16 eina_f16p16_sqrt(Eina_F16p16 a); -static inline unsigned int eina_f16p16_fracc_get(Eina_F16p16 v); - -static inline Eina_F8p24 eina_f8p24_int_from(int32_t v); -static inline int32_t eina_f8p24_int_to(Eina_F8p24 v); -static inline Eina_F8p24 eina_f8p24_float_from(float v); -static inline float eina_f8p24_float_to(Eina_F8p24 v); - -static inline Eina_F8p24 eina_f8p24_add(Eina_F8p24 a, Eina_F8p24 b); -static inline Eina_F8p24 eina_f8p24_sub(Eina_F8p24 a, Eina_F8p24 b); -static inline Eina_F8p24 eina_f8p24_mul(Eina_F8p24 a, Eina_F8p24 b); -static inline Eina_F8p24 eina_f8p24_scale(Eina_F8p24 a, int b); -static inline Eina_F8p24 eina_f8p24_div(Eina_F8p24 a, Eina_F8p24 b); -static inline Eina_F8p24 eina_f8p24_sqrt(Eina_F8p24 a); -static inline unsigned int eina_f8p24_fracc_get(Eina_F8p24 v); - -static inline Eina_F32p32 eina_f16p16_to_f32p32(Eina_F16p16 a); -static inline Eina_F32p32 eina_f8p24_to_f32p32(Eina_F8p24 a); -static inline Eina_F16p16 eina_f32p32_to_f16p16(Eina_F32p32 a); -static inline Eina_F16p16 eina_f8p24_to_f16p16(Eina_F8p24 a); -static inline Eina_F8p24 eina_f32p32_to_f8p24(Eina_F32p32 a); -static inline Eina_F8p24 eina_f16p16_to_f8p24(Eina_F16p16 a); - -#include "eina_inline_f32p32.x" -#include "eina_inline_f16p16.x" -#include "eina_inline_f8p24.x" -#include "eina_inline_fp.x" - -#endif diff --git a/tests/suite/ecore/src/include/eina_hamster.h b/tests/suite/ecore/src/include/eina_hamster.h deleted file mode 100644 index c01198946c..0000000000 --- a/tests/suite/ecore/src/include/eina_hamster.h +++ /dev/null @@ -1,44 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_HAMSTER_H_ -#define EINA_HAMSTER_H_ - -/** - * @addtogroup Eina_Core_Group Core - * - * @{ - */ - -/** - * @defgroup Eina_Hamster_Group Hamster - * - * @{ - */ - -EAPI int eina_hamster_count(void); - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_HAMSTER_H_ */ diff --git a/tests/suite/ecore/src/include/eina_hash.h b/tests/suite/ecore/src/include/eina_hash.h deleted file mode 100644 index b19e8e24f6..0000000000 --- a/tests/suite/ecore/src/include/eina_hash.h +++ /dev/null @@ -1,176 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Gustavo Sverzut Barbieri, - * Vincent Torri, Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_HASH_H_ -#define EINA_HASH_H_ - -#include "eina_types.h" -#include "eina_iterator.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_Hash_Group Hash Table - * - * @{ - */ - -/** - * @typedef Eina_Hash - * Type for a generic hash table. - */ -typedef struct _Eina_Hash Eina_Hash; - -typedef struct _Eina_Hash_Tuple Eina_Hash_Tuple; - -struct _Eina_Hash_Tuple { - const void *key; - /**< The key */ - void *data; - /**< The data associated to the key */ - unsigned int key_length; - /**< The length of the key */ -}; - -typedef unsigned int (*Eina_Key_Length) (const void *key); -#define EINA_KEY_LENGTH(Function) ((Eina_Key_Length)Function) -typedef int (*Eina_Key_Cmp) (const void *key1, int key1_length, - const void *key2, int key2_length); -#define EINA_KEY_CMP(Function) ((Eina_Key_Cmp)Function) -typedef int (*Eina_Key_Hash) (const void *key, int key_length); -#define EINA_KEY_HASH(Function) ((Eina_Key_Hash)Function) -typedef Eina_Bool(*Eina_Hash_Foreach) (const Eina_Hash * hash, - const void *key, void *data, - void *fdata); - -EAPI Eina_Hash *eina_hash_new(Eina_Key_Length key_length_cb, - Eina_Key_Cmp key_cmp_cb, - Eina_Key_Hash key_hash_cb, - Eina_Free_Cb data_free_cb, - int buckets_power_size) -EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(2, 3); -EAPI Eina_Hash *eina_hash_string_djb2_new(Eina_Free_Cb data_free_cb); -EAPI Eina_Hash *eina_hash_string_superfast_new(Eina_Free_Cb data_free_cb); -EAPI Eina_Hash *eina_hash_string_small_new(Eina_Free_Cb data_free_cb); -EAPI Eina_Hash *eina_hash_int32_new(Eina_Free_Cb data_free_cb); -EAPI Eina_Hash *eina_hash_int64_new(Eina_Free_Cb data_free_cb); -EAPI Eina_Hash *eina_hash_pointer_new(Eina_Free_Cb data_free_cb); -EAPI Eina_Hash *eina_hash_stringshared_new(Eina_Free_Cb data_free_cb); -EAPI Eina_Bool eina_hash_add(Eina_Hash * hash, - const void *key, - const void *data) EINA_ARG_NONNULL(1, 2, 3); -EAPI Eina_Bool eina_hash_direct_add(Eina_Hash * hash, - const void *key, - const void *data) EINA_ARG_NONNULL(1, - 2, - 3); -EAPI Eina_Bool eina_hash_del(Eina_Hash * hash, const void *key, - const void *data) EINA_ARG_NONNULL(1); -EAPI void *eina_hash_find(const Eina_Hash * hash, - const void *key) EINA_ARG_NONNULL(1, 2); -EAPI void *eina_hash_modify(Eina_Hash * hash, const void *key, - const void *data) EINA_ARG_NONNULL(1, 2, 3); -EAPI void *eina_hash_set(Eina_Hash * hash, const void *key, - const void *data) EINA_ARG_NONNULL(1, 2, 3); -EAPI Eina_Bool eina_hash_move(Eina_Hash * hash, const void *old_key, - const void *new_key) EINA_ARG_NONNULL(1, 2, - 3); -EAPI void eina_hash_free(Eina_Hash * hash) EINA_ARG_NONNULL(1); -EAPI void eina_hash_free_buckets(Eina_Hash * hash) EINA_ARG_NONNULL(1); -EAPI int eina_hash_population(const Eina_Hash * hash) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_hash_add_by_hash(Eina_Hash * hash, - const void *key, - int key_length, - int key_hash, - const void *data) EINA_ARG_NONNULL(1, - 2, - 5); -EAPI Eina_Bool eina_hash_direct_add_by_hash(Eina_Hash * hash, - const void *key, - int key_length, int key_hash, - const void *data) -EINA_ARG_NONNULL(1, 2, 5); -EAPI Eina_Bool eina_hash_del_by_key_hash(Eina_Hash * hash, const void *key, - int key_length, - int key_hash) EINA_ARG_NONNULL(1, - 2); -EAPI Eina_Bool eina_hash_del_by_key(Eina_Hash * hash, - const void *key) EINA_ARG_NONNULL(1, - 2); -EAPI Eina_Bool eina_hash_del_by_data(Eina_Hash * hash, - const void *data) EINA_ARG_NONNULL(1, - 2); -EAPI Eina_Bool eina_hash_del_by_hash(Eina_Hash * hash, const void *key, - int key_length, int key_hash, - const void *data) EINA_ARG_NONNULL(1); -EAPI void *eina_hash_find_by_hash(const Eina_Hash * hash, const void *key, - int key_length, - int key_hash) EINA_ARG_NONNULL(1, 2); -EAPI void *eina_hash_modify_by_hash(Eina_Hash * hash, const void *key, - int key_length, int key_hash, - const void *data) EINA_ARG_NONNULL(1, - 2, - 5); -EAPI Eina_Iterator *eina_hash_iterator_key_new(const Eina_Hash * hash) -EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Iterator *eina_hash_iterator_data_new(const Eina_Hash * hash) -EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Iterator *eina_hash_iterator_tuple_new(const Eina_Hash * hash) -EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -EAPI void eina_hash_foreach(const Eina_Hash * hash, - Eina_Hash_Foreach cb, - const void *fdata) EINA_ARG_NONNULL(1, 2); -/* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html) hash function used by WebCore (http://webkit.org/blog/8/hashtables-part-2/) */ -EAPI int eina_hash_superfast(const char *key, int len) EINA_ARG_NONNULL(1); -/* Hash function first reported by dan bernstein many years ago in comp.lang.c */ -static inline int eina_hash_djb2(const char *key, - int len) EINA_ARG_NONNULL(1); -static inline int eina_hash_djb2_len(const char *key, - int *plen) EINA_ARG_NONNULL(1, 2); -/* Hash function from http://www.concentric.net/~Ttwang/tech/inthash.htm */ -static inline int eina_hash_int32(const unsigned int *pkey, - int len) EINA_ARG_NONNULL(1); -static inline int eina_hash_int64(const unsigned long int *pkey, - int len) EINA_ARG_NONNULL(1); - -#include "eina_inline_hash.x" - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /*EINA_HASH_H_ */ diff --git a/tests/suite/ecore/src/include/eina_inline_array.x b/tests/suite/ecore/src/include/eina_inline_array.x deleted file mode 100644 index 7e77151caa..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_array.x +++ /dev/null @@ -1,181 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_ARRAY_X_ -#define EINA_INLINE_ARRAY_X_ - -#include <stdio.h> - -/** - * @cond LOCAL - */ - -EAPI Eina_Bool eina_array_grow(Eina_Array *array); - -/** - * @endcond - */ - -/** - * @addtogroup Eina_Array_Group Array - * - * @brief These functions provide array management. - * - * @{ - */ - -/** - * @brief Append a data to an array. - * - * @param array The array. - * @param data The data to add. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function appends @p data to @p array. For performance - * reasons, there is no check of @p array. If it is @c NULL or - * invalid, the program may crash. If @p data is @c NULL, or if an - * allocation is necessary and fails, #EINA_FALSE is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, #EINA_TRUE is - * returned. - */ - -static inline Eina_Bool -eina_array_push(Eina_Array *array, const void *data) -{ - if (!data) return EINA_FALSE; - - if (EINA_UNLIKELY((array->count + 1) > array->total)) - if (!eina_array_grow(array)) - return EINA_FALSE; - - array->data[array->count++] = (void*) data; - - return EINA_TRUE; -} - -/** - * @brief Remove the last data of an array. - * - * @param array The array. - * @return The retrieved data. - * - * This function removes the last data of @p array, decreases the count - * of @p array and returns the data. For performance reasons, there - * is no check of @p array. If it is @c NULL or invalid, the program - * may crash. If the count member is less or equal than 0, @c NULL is - * returned. - */ -static inline void * -eina_array_pop(Eina_Array *array) -{ - void *ret = NULL; - - if (array->count <= 0) - goto on_empty; - - ret = array->data[--array->count]; - - on_empty: - return ret; -} - -/** - * @brief Return the data at a given position in an array. - * - * @param array The array. - * @param idx The potition of the data to retrieve. - * @return The retrieved data. - * - * This function returns the data at the position @p idx in @p - * array. For performance reasons, there is no check of @p array or @p - * idx. If it is @c NULL or invalid, the program may crash. - */ -static inline void * -eina_array_data_get(const Eina_Array *array, unsigned int idx) -{ - return array->data[idx]; -} - -/** - * @brief Set the data at a given position in an array. - * - * @param array The array. - * @param idx The potition of the data to set. - * @param data The data to set. - * - * This function sets the data at the position @p idx in @p - * array. For performance reasons, there is no check of @p array or @p - * idx. If it is @c NULL or invalid, the program may crash. - */ -static inline void -eina_array_data_set(const Eina_Array *array, unsigned int idx, const void *data) -{ - array->data[idx] = (void*) data; -} - -/** - * @brief Return the number of elements in an array. - * - * @param array The array. - * @return The number of elements. - * - * This function returns the number of elements in @p array. For - * performance reasons, there is no check of @p array. If it is - * @c NULL or invalid, the program may crash. - */ -static inline unsigned int -eina_array_count_get(const Eina_Array *array) -{ - return array->count; -} - -/** - * @brief Provide a safe way to iterate over an array - * - * @param array The array to iterate over. - * @param cb The callback to call for each item. - * @param fdata The user data to pass to the callback. - * @return EINA_TRUE if it successfully iterate all items of the array. - * - * This function provide a safe way to iterate over an array. @p cb should - * return EINA_TRUE as long as you want the function to continue iterating, - * by returning EINA_FALSE it will stop and return EINA_FALSE as a result. - */ -static inline Eina_Bool -eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata) -{ - void *data; - Eina_Array_Iterator iterator; - unsigned int i; - Eina_Bool ret = EINA_TRUE; - - EINA_ARRAY_ITER_NEXT(array, i, data, iterator) - if (cb(array, data, fdata) != EINA_TRUE) - { - ret = EINA_FALSE; - break; - } - - return ret; -} - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_f16p16.x b/tests/suite/ecore/src/include/eina_inline_f16p16.x deleted file mode 100644 index 28edd2c0da..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_f16p16.x +++ /dev/null @@ -1,83 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * Copyright (C) 2009 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_F16P16_X_ -#define EINA_INLINE_F16P16_X_ - -static inline Eina_F16p16 -eina_f16p16_add(Eina_F16p16 a, Eina_F16p16 b) -{ - return a + b; -} - -static inline Eina_F16p16 -eina_f16p16_sub(Eina_F16p16 a, Eina_F16p16 b) -{ - return a - b; -} - -static inline Eina_F16p16 -eina_f16p16_mul(Eina_F16p16 a, Eina_F16p16 b) -{ - return (Eina_F16p16)(((int64_t)a * (int64_t)b) >> 16); -} - -static inline Eina_F16p16 -eina_f16p16_scale(Eina_F16p16 a, int b) -{ - return a * b; -} - -static inline Eina_F16p16 -eina_f16p16_div(Eina_F16p16 a, Eina_F16p16 b) -{ - return (Eina_F16p16) ((((int64_t) a) << 16) / (int64_t) b); -} - -static inline Eina_F16p16 -eina_f16p16_sqrt(Eina_F16p16 a) -{ - unsigned int root, remHi, remLo, testDiv, count; - - root = 0; /* Clear root */ - remHi = 0; /* Clear high part of partial remainder */ - remLo = a; /* Get argument into low part of partial remainder */ - count = (15 + (16 >> 1)); /* Load loop counter */ - do { - remHi = (remHi << 2) | (remLo >> 30); - remLo <<= 2; /* get 2 bits of arg */ - root <<= 1; /* Get ready for the next bit in the root */ - testDiv = (root << 1) + 1; /* Test radical */ - if (remHi >= testDiv) - { - remHi -= testDiv; - root++; - } - } while (count-- != 0); - - return root; -} - -static inline unsigned int -eina_f16p16_fracc_get(Eina_F16p16 v) -{ - return (v & 0xffff); -} - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_f32p32.x b/tests/suite/ecore/src/include/eina_inline_f32p32.x deleted file mode 100644 index c76f8d370a..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_f32p32.x +++ /dev/null @@ -1,110 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2009 Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_F32P32_X_ -# define EINA_INLINE_F32P32_X_ - -#include <stdlib.h> - -static inline Eina_F32p32 -eina_f32p32_add(Eina_F32p32 a, Eina_F32p32 b) -{ - return a + b; -} - -static inline Eina_F32p32 -eina_f32p32_sub(Eina_F32p32 a, Eina_F32p32 b) -{ - return a - b; -} - -static inline Eina_F32p32 -eina_f32p32_mul(Eina_F32p32 a, Eina_F32p32 b) -{ - /* Prevent overflow and do '(a * b) >> 32' */ - /* Basically do: Eina_F16p16 * Eina_F16p16 = Eina_F32p32 */ - Eina_F32p32 up; - Eina_F32p32 down; - Eina_F32p32 result; - uint64_t as, bs; - Eina_F32p32 sign; - - sign = a ^ b; - as = eina_fp32p32_llabs(a); - bs = eina_fp32p32_llabs(b); - - up = (as >> 16) * (bs >> 16); - down = (as & 0xFFFF) * (bs & 0xFFFF); - - result = up + (down >> 32); - - return sign < 0 ? - result : result; -} - -static inline Eina_F32p32 -eina_f32p32_scale(Eina_F32p32 a, int b) -{ - return a * b; -} - -static inline Eina_F32p32 -eina_f32p32_div(Eina_F32p32 a, Eina_F32p32 b) -{ - Eina_F32p32 sign; - Eina_F32p32 result; - - sign = a ^ b; - - if (b == 0) - return sign < 0 ? (Eina_F32p32) 0x8000000000000000ull : (Eina_F32p32) 0x7FFFFFFFFFFFFFFFull; - - result = (eina_f32p32_mul(eina_fp32p32_llabs(a), (((uint64_t) 1 << 62) / ((uint64_t)(eina_fp32p32_llabs(b)) >> 2)))); - - return sign < 0 ? - result : result; -} - -static inline Eina_F32p32 -eina_f32p32_sqrt(Eina_F32p32 a) -{ - uint64_t root, remHi, remLo, testDiv, count; - - root = 0; /* Clear root */ - remHi = 0; /* Clear high part of partial remainder */ - remLo = a; /* Get argument into low part of partial remainder */ - count = (31 + (32 >> 1)); /* Load loop counter */ - do { - remHi = (remHi << 2) | (remLo >> 30); - remLo <<= 2; /* get 2 bits of arg */ - root <<= 1; /* Get ready for the next bit in the root */ - testDiv = (root << 1) + 1; /* Test radical */ - if (remHi >= testDiv) { - remHi -= testDiv; - root++; - } - } while (count-- != 0); - - return root; -} - -static inline unsigned int -eina_f32p32_fracc_get(Eina_F32p32 v) -{ - return (unsigned int)v; -} - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_f8p24.x b/tests/suite/ecore/src/include/eina_inline_f8p24.x deleted file mode 100644 index b17f4bdbc3..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_f8p24.x +++ /dev/null @@ -1,82 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * Copyright (C) 2009 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_F8P24_X_ -#define EINA_INLINE_F8P24_X_ - -static inline Eina_F8p24 -eina_f8p24_add(Eina_F8p24 a, Eina_F8p24 b) -{ - return a + b; -} - -static inline Eina_F8p24 -eina_f8p24_sub(Eina_F8p24 a, Eina_F8p24 b) -{ - return a - b; -} - -static inline Eina_F8p24 -eina_f8p24_mul(Eina_F8p24 a, Eina_F8p24 b) -{ - return (Eina_F8p24)(((int64_t) a * (int64_t) b) >> 24); -} - -static inline Eina_F8p24 -eina_f8p24_scale(Eina_F8p24 a, int b) -{ - return a * b; -} - -static inline Eina_F8p24 -eina_f8p24_div(Eina_F8p24 a, Eina_F8p24 b) -{ - return (Eina_F8p24) ((((int64_t) a) << 24) / (int64_t) b); -} - -static inline Eina_F8p24 -eina_f8p24_sqrt(Eina_F8p24 a) -{ - unsigned int root, remHi, remLo, testDiv, count; - - root = 0; /* Clear root */ - remHi = 0; /* Clear high part of partial remainder */ - remLo = a; /* Get argument into low part of partial remainder */ - count = (23 + (24 >> 1)); /* Load loop counter */ - do { - remHi = (remHi << 2) | (remLo >> 30); - remLo <<= 2; /* get 2 bits of arg */ - root <<= 1; /* Get ready for the next bit in the root */ - testDiv = (root << 1) + 1; /* Test radical */ - if (remHi >= testDiv) - { - remHi -= testDiv; - root++; - } - } while (count-- != 0); - return (root); -} - -static inline unsigned int -eina_f8p24_fracc_get(Eina_F8p24 v) -{ - return (v & 0xffffff); -} - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_fp.x b/tests/suite/ecore/src/include/eina_inline_fp.x deleted file mode 100644 index a36e66bd30..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_fp.x +++ /dev/null @@ -1,153 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * Copyright (C) 2009 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_FP_X_ -# define EINA_INLINE_FP_X_ - -static inline Eina_F32p32 -eina_f32p32_int_from(int32_t v) -{ - return (Eina_F32p32)(v) << 32; -} - -static inline int32_t -eina_f32p32_int_to(Eina_F32p32 v) -{ - return (int32_t)(v >> 32); -} - -static inline Eina_F32p32 -eina_f32p32_double_from(double v) -{ - Eina_F32p32 r; - r = (Eina_F32p32)(v * 4294967296.0 + (v < 0 ? -0.5 : 0.5)); - return r; -} - -static inline double -eina_f32p32_double_to(Eina_F32p32 v) -{ - double r; - r = v / 4294967296.0; - return r; -} - - - -static inline Eina_F16p16 -eina_f16p16_int_from(int32_t v) -{ - return v << 16; -} - -static inline int32_t -eina_f16p16_int_to(Eina_F16p16 v) -{ - return v >> 16; -} - -static inline Eina_F16p16 -eina_f16p16_float_from(float v) -{ - Eina_F16p16 r; - - r = (Eina_F16p16)(v * 65536.0f + (v < 0 ? -0.5f : 0.5f)); - return r; -} - -static inline float -eina_f16p16_float_to(Eina_F16p16 v) -{ - float r; - - r = v / 65536.0f; - return r; -} - - - -static inline Eina_F8p24 -eina_f8p24_int_from(int32_t v) -{ - return v << 24; -} - -static inline int32_t -eina_f8p24_int_to(Eina_F8p24 v) -{ - return v >> 24; -} - -static inline Eina_F8p24 -eina_f8p24_float_from(float v) -{ - Eina_F8p24 r; - - r = (Eina_F8p24)(v * 16777216.0f + (v < 0 ? -0.5f : 0.5f)); - return r; -} - -static inline float -eina_f8p24_float_to(Eina_F8p24 v) -{ - float r; - - r = v / 16777216.0f; - return r; -} - - - -static inline Eina_F32p32 -eina_f16p16_to_f32p32(Eina_F16p16 a) -{ - return ((Eina_F32p32) a) << 16; -} - -static inline Eina_F32p32 -eina_f8p24_to_f32p32(Eina_F8p24 a) -{ - return ((Eina_F32p32) a) << 8; -} - -static inline Eina_F16p16 -eina_f32p32_to_f16p16(Eina_F32p32 a) -{ - return (Eina_F16p16) (a >> 16); -} - -static inline Eina_F16p16 -eina_f8p24_to_f16p16(Eina_F8p24 a) -{ - return (Eina_F16p16) (a >> 8); -} - -static inline Eina_F8p24 -eina_f32p32_to_f8p24(Eina_F32p32 a) -{ - return (Eina_F8p24) (a >> 8); -} - -static inline Eina_F8p24 -eina_f16p16_to_f8p24(Eina_F16p16 a) -{ - return (Eina_F8p24) (a << 8); -} - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_hash.x b/tests/suite/ecore/src/include/eina_inline_hash.x deleted file mode 100644 index 3d74db2cdd..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_hash.x +++ /dev/null @@ -1,88 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_HASH_X_ -#define EINA_INLINE_HASH_X_ - -/* - djb2 hash algorithm was first reported by dan bernstein, and was the old - default hash function for evas. - */ -static inline int -eina_hash_djb2(const char *key, int len) -{ - unsigned int hash_num = 5381; - const unsigned char *ptr; - - if (!key) return 0; - for (ptr = (unsigned char *)key; len; ptr++, len--) - hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ - - return (int)hash_num; -} - -static inline int -eina_hash_djb2_len(const char *key, int *plen) -{ - unsigned int hash_num = 5381; - int len = 0; - const unsigned char *ptr; - - if (!key) return 0; - - for (ptr = (unsigned char *)key; *ptr; ptr++, len++) - hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ - - *plen = len + 1; - - return (int)hash_num; -} - -static inline int -eina_hash_int32(const unsigned int *pkey, int len) -{ - unsigned int key = *pkey; - - (void) len; - - key = ~key + (key << 15); - key = key ^ (key >> 12); - key = key + (key << 2); - key = key ^ (key >> 4); - key = key * 2057; - key = key ^ (key >> 16); - return key; -} - -static inline int -eina_hash_int64(const unsigned long int *pkey, int len) -{ - unsigned long int key = *pkey; - - (void) len; - - key = (~key) + (key << 18); - key = key ^ (key >> 31); - key = key * 21; - key = key ^ (key >> 11); - key = key + (key << 6); - key = key ^ (key >> 22); - return (int) key; -} - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_list.x b/tests/suite/ecore/src/include/eina_inline_list.x deleted file mode 100644 index adbec94f8b..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_list.x +++ /dev/null @@ -1,145 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Vincent Torri, Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_LIST_INLINE_H_ -#define EINA_LIST_INLINE_H_ - -/** - * @addtogroup Eina_List_Group List - * - * @brief These functions provide list management. - * - * @{ - */ - -/** - * @brief Get the last list node in the list. - * - * @param list The list to get the last list node from. - * @return The last list node in the list. - * - * This function returns the last list node in the list @p list. If - * @p list is @c NULL or empty, @c NULL is returned. - * - * This is a order-1 operation (it takes the same short time - * regardless of the length of the list). - */ -static inline Eina_List * -eina_list_last(const Eina_List *list) -{ - if (!list) return NULL; - return list->accounting->last; -} - -/** - * @brief Get the next list node after the specified list node. - * - * @param list The list node to get the next list node from - * @return The next list node on success, @c NULL otherwise. - * - * This function returns the next list node after the current one in - * @p list. It is equivalent to list->next. If @p list is @c NULL or - * if no next list node exists, it returns @c NULL. - */ -static inline Eina_List * -eina_list_next(const Eina_List *list) -{ - if (!list) return NULL; - return list->next; -} - -/** - * @brief Get the previous list node before the specified list node. - * - * @param list The list node to get the previous list node from. - * @return The previous list node o success, @c NULL otherwise. - * if no previous list node exists - * - * This function returns the previous list node before the current one - * in @p list. It is equivalent to list->prev. If @p list is @c NULL or - * if no previous list node exists, it returns @c NULL. - */ -static inline Eina_List * -eina_list_prev(const Eina_List *list) -{ - if (!list) return NULL; - return list->prev; -} - -/** - * @brief Get the list node data member. - * - * @param list The list node to get the data member of. - * @return The data member from the list node. - * - * This function returns the data member of the specified list node @p - * list. It is equivalent to list->data. If @p list is @c NULL, this - * function returns @c NULL. - */ -static inline void * -eina_list_data_get(const Eina_List *list) -{ - if (!list) return NULL; - return list->data; -} - -/** - * @brief Set the list node data member. - * - * @param list The list node to get the data member of. - * @param data The data member to the list node. - * @return The previous data value. - * - * This function set the data member @p data of the specified list node - * @p list. It returns the previous data of the node. If @p list is - * @c NULL, this function returns @c NULL. - */ -static inline void * -eina_list_data_set(Eina_List *list, const void *data) -{ - void *tmp; - if (!list) return NULL; - tmp = list->data; - list->data = (void*) data; - return tmp; -} - -/** - * @brief Get the count of the number of items in a list. - * - * @param list The list whose count to return. - * @return The number of members in the list. - * - * This function returns how many members @p list contains. If the - * list is @c NULL, 0 is returned. - * - * NB: This is an order-1 operation and takes the same time regardless - * of the length of the list. - */ -static inline unsigned int -eina_list_count(const Eina_List *list) -{ - if (!list) return 0; - return list->accounting->count; -} - -/** - * @} - */ - -#endif /* EINA_LIST_INLINE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_inline_log.x b/tests/suite/ecore/src/include/eina_inline_log.x deleted file mode 100644 index 2041614ae8..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_log.x +++ /dev/null @@ -1,197 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_LOG_INLINE_H_ -#define EINA_LOG_INLINE_H_ - -/** - * @addtogroup Eina_Log_Group Log - * - * @{ - */ - -/** - * Checks whenever the given level should be printed out. - * - * This is useful to enable certain blocks of code just when given - * level is to be used. - * - * @code - * #include <Eina.h> - * - * void my_func(void *data) - * { - * if (eina_log_level_check(EINA_LOG_LEVEL_WARN)) - * expensive_debugging_code(data); - * - * my_func_code(data); - * } - * @endcode - * - * @return #EINA_TRUE if level is equal or smaller than the current global - * logging level. - */ -static inline Eina_Bool -eina_log_level_check(int level) -{ - return eina_log_level_get() <= level; -} - -/** - * Checks whenever the given level should be printed out. - * - * This is useful to enable certain blocks of code just when given - * level is to be used. - * - * @code - * #include <Eina.h> - * - * extern int _my_log_dom; - * - * void my_func(void *data) - * { - * if (eina_log_domain_level_check(_my_log_dom, EINA_LOG_LEVEL_WARN)) - * expensive_debugging_code(data); - * - * my_func_code(data); - * } - * @endcode - * - * @return #EINA_TRUE if level is equal or smaller than the current - * domain logging level. - */ -static inline Eina_Bool -eina_log_domain_level_check(int domain, int level) -{ - int dom_level = eina_log_domain_registered_level_get(domain); - if (EINA_UNLIKELY(dom_level == EINA_LOG_LEVEL_UNKNOWN)) - return EINA_FALSE; - return dom_level <= level; -} - -/** - * Function to format the level as a 3 character (+1 null byte) string. - * - * This function converts the given level to a known string name (CRI, - * ERR, WRN, INF or DBG) or a zero-padded 3-character string. In any - * case the last byte will contain a trailing null byte. - * - * If extreme level values are used (greater than 999 and smaller than - * -99), then the value will just consider the less significant - * part. This is so uncommon that users should handle this in their - * code. - * - * @param level what level value to use. - * @param name where to write the actual value. - * - * @return pointer to @p name. - */ -static inline const char * -eina_log_level_name_get(int level, char name[4]) -{ -#define BCPY(A, B, C) \ - do { name[0] = A; name[1] = B; name[2] = C; } while (0) - - if (EINA_UNLIKELY(level < 0)) - { - name[0] = '-'; - name[1] = '0' + (-level / 10) % 10; - name[2] = '0' + (-level % 10); - } - else if (EINA_UNLIKELY(level >= EINA_LOG_LEVELS)) - { - name[0] = '0' + (level / 100) % 10; - name[1] = '0' + (level / 10) % 10; - name[2] = '0' + level % 10; - } - else if (level == 0) - BCPY('C', 'R', 'I'); - else if (level == 1) - BCPY('E', 'R', 'R'); - else if (level == 2) - BCPY('W', 'R', 'N'); - else if (level == 3) - BCPY('I', 'N', 'F'); - else if (level == 4) - BCPY('D', 'B', 'G'); - else - BCPY('?', '?', '?'); - - name[3] = '\0'; - - return name; -} - -/** - * Function to get recommended color value for level. - * - * This function will not check if colors are enabled or not before - * returning the level color. If you desire such check, use - * eina_log_level_color_if_enabled_get(). - * - * @param level what level value to use. - * - * @return pointer to null byte terminated ANSI color string to be - * used in virtual terminals supporting VT100 color codes. - * - * @see eina_log_level_color_if_enabled_get() - */ -static inline const char * -eina_log_level_color_get(int level) -{ - if (level <= 0) - return EINA_COLOR_LIGHTRED; - else if (level == 1) - return EINA_COLOR_RED; - else if (level == 2) - return EINA_COLOR_YELLOW; - else if (level == 3) - return EINA_COLOR_GREEN; - else if (level == 4) - return EINA_COLOR_LIGHTBLUE; - else - return EINA_COLOR_BLUE; -} - -/** - * Function to get recommended color value for level, if colors are - * enabled. - * - * This function will check if colors are enabled or not before - * returning the level color. If colors are disabled, then empty - * string is returned. - * - * @param level what level value to use. - * - * @return pointer to null byte terminated ANSI color string to be - * used in virtual terminals supporting VT100 color codes. If - * colors are disabled, the empty string is returned. - */ -static inline const char * -eina_log_level_color_if_enabled_get(int level) -{ - if (eina_log_color_disable_get()) - return ""; - return eina_log_level_color_get(level); -} - -/** - * @} - */ - -#endif /* EINA_LOG_INLINE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_inline_mempool.x b/tests/suite/ecore/src/include/eina_inline_mempool.x deleted file mode 100644 index 00cebe67bd..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_mempool.x +++ /dev/null @@ -1,105 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_MEMPOOL_X_ -#define EINA_INLINE_MEMPOOL_X_ - -/** - * @addtogroup Eina_Memory_Pool_Group Memory Pool - * - * @{ - */ - -/* Memory Pool */ -struct _Eina_Mempool_Backend -{ - const char *name; - void *(*init)(const char *context, const char *options, va_list args); - void (*free)(void *data, void *element); - void *(*alloc)(void *data, unsigned int size); - void *(*realloc)(void *data, void *element, unsigned int size); - void (*garbage_collect)(void *data); - void (*statistics)(void *data); - void (*shutdown)(void *data); -}; - -struct _Eina_Mempool -{ - Eina_Mempool_Backend backend; - void *backend_data; -}; - -/** - * @brief Re-allocate a amount memory by the given mempool. - * - * @param mp The mempool. - * @param element The element to re-allocate. - * @param size The size in bytes to re-allocate. - * @return The newly re-allocated data. - * - * This function re-allocates @p element with @p size bytes, using the - * mempool @p mp and returns the allocated data. If not used anymore, - * the data must be freed with eina_mempool_free(). No check is done - * on @p mp, so it must be a valid mempool. - */ -static inline void * -eina_mempool_realloc(Eina_Mempool *mp, void *element, unsigned int size) -{ - return mp->backend.realloc(mp->backend_data, element, size); -} - -/** - * @brief Allocate a amount memory by the given mempool. - * - * @param mp The mempool. - * @param size The size in bytes to allocate. - * @return The newly allocated data. - * - * This function allocates @p size bytes, using the mempool @p mp and - * returns the allocated data. If not used anymore, the data must be - * freed with eina_mempool_free(). No check is done on @p mp, so it - * must be a valid mempool. - */ -static inline void * -eina_mempool_malloc(Eina_Mempool *mp, unsigned int size) -{ - return mp->backend.alloc(mp->backend_data, size); -} - -/** - * @brief Free the allocated ressources by the given mempool. - * - * @param mp The mempool. - * @param element The data to free. - * - * This function frees @p element allocated by @p mp. @p element must - * have been obtained by eina_mempool_malloc() or - * eina_mempool_realloc(). No check is done on @p mp, so it must be a - * valid mempool. - */ -static inline void -eina_mempool_free(Eina_Mempool *mp, void *element) -{ - mp->backend.free(mp->backend_data, element); -} - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_rbtree.x b/tests/suite/ecore/src/include/eina_inline_rbtree.x deleted file mode 100644 index 6a30c78099..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_rbtree.x +++ /dev/null @@ -1,50 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_RBTREE_INLINE_H_ -#define EINA_RBTREE_INLINE_H_ - -/** - * @addtogroup Eina_Rbtree_Group Red-Black tree - * - * @brief These functions provide Red-Black trees management. - * - * @{ - */ - -static inline Eina_Rbtree * -eina_rbtree_inline_lookup(const Eina_Rbtree *root, const void *key, int length, Eina_Rbtree_Cmp_Key_Cb cmp, const void *data) -{ - int result; - - while (root) - { - result = cmp(root, key, length, (void*) data); - if (result == 0) return (Eina_Rbtree*) root; - - root = root->son[result < 0 ? 0 : 1]; - } - - return NULL; -} - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_rectangle.x b/tests/suite/ecore/src/include/eina_inline_rectangle.x deleted file mode 100644 index fa4696c61f..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_rectangle.x +++ /dev/null @@ -1,254 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_RECTANGLE_H__ -#define EINA_INLINE_RECTANGLE_H__ - -/** - * @addtogroup Eina_Rectangle_Group Rectangle - * - * @brief These functions provide rectangle management. - * - * @{ - */ - -/** - * @brief Check if the given spans intersect. - * - * @param c1 The column of the first span. - * @param l1 The length of the first span. - * @param c2 The column of the second span. - * @param l2 The length of the second span. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if the given spans intersect, - * #EINA_FALSE otherwise. - */ -static inline int -eina_spans_intersect(int c1, int l1, int c2, int l2) -{ - return (!(((c2 + l2) <= c1) || (c2 >= (c1 + l1)))); -} - -/** - * @brief Check if the given rectangle is empty. - * - * @param r The rectangle to check. - * @return #EINA_TRUE if the rectangle is empty, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if @p r is empty, #EINA_FALSE - * otherwise. No check is done on @p r, so it must be a valid - * rectangle. - */ -static inline Eina_Bool -eina_rectangle_is_empty(const Eina_Rectangle *r) -{ - return ((r->w < 1) || (r->h < 1)) ? EINA_TRUE : EINA_FALSE; -} - -/** - * @brief Set the coordinates and size of the given rectangle. - * - * @param r The rectangle. - * @param x The top-left x coordinate of the rectangle. - * @param y The top-left y coordinate of the rectangle. - * @param w The width of the rectangle. - * @param h The height of the rectangle. - * - * This function sets its top-left x coordinate to @p x, its top-left - * y coordinate to @p y, its width to @p w and its height to @p h. No - * check is done on @p r, so it must be a valid rectangle. - */ -static inline void -eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h) -{ - r->x = x; - r->y = y; - r->w = w; - r->h = h; -} - -/** - * @brief Check if the given rectangles intersect. - * - * @param r1 The first rectangle. - * @param r2 The second rectangle. - * @return #EINA_TRUE if the rectangles intersect, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if @p r1 and @p r2 intersect, - * #EINA_FALSE otherwise. No check is done on @p r1 and @p r2, so they - * must be valid rectangles. - */ -static inline Eina_Bool -eina_rectangles_intersect(const Eina_Rectangle *r1, const Eina_Rectangle *r2) -{ - return (eina_spans_intersect(r1->x, r1->w, r2->x, r2->w) && eina_spans_intersect(r1->y, r1->h, r2->y, r2->h)) ? EINA_TRUE : EINA_FALSE; -} - -/** - * @brief Check if the given x-coordinate is in the rectangle . - * - * @param r The rectangle. - * @param x The x coordinate. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if @p x is in @p r with respect to - * the horizontal direction, #EINA_FALSE otherwise. No check is done - * on @p r, so it must be a valid rectangle. - */ -static inline Eina_Bool -eina_rectangle_xcoord_inside(const Eina_Rectangle *r, int x) -{ - return ((x >= r->x) && (x < (r->x + r->w))) ? EINA_TRUE : EINA_FALSE; -} - -/** - * @brief Check if the given y-coordinate is in the rectangle . - * - * @param r The rectangle. - * @param y The y coordinate. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if @p y is in @p r with respect to - * the vertical direction, #EINA_FALSE otherwise. No check is done - * on @p r, so it must be a valid rectangle. - */ -static inline Eina_Bool -eina_rectangle_ycoord_inside(const Eina_Rectangle *r, int y) -{ - return ((y >= r->y) && (y < (r->y + r->h))) ? EINA_TRUE : EINA_FALSE; -} - -/** - * @brief Check if the given point is in the rectangle . - * - * @param r The rectangle. - * @param x The x coordinate of the point. - * @param y The y coordinate of the point. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if the point of coordinate (@p x, - * @p y) is in @p r, #EINA_FALSE otherwise. No check is done on @p r, - * so it must be a valid rectangle. - */ -static inline Eina_Bool -eina_rectangle_coords_inside(const Eina_Rectangle *r, int x, int y) -{ - return (eina_rectangle_xcoord_inside(r, x) && eina_rectangle_ycoord_inside(r, y)) ? EINA_TRUE : EINA_FALSE; -} - -/** - * @brief Get the union of two rectangles. - * - * @param dst The first rectangle. - * @param src The second rectangle. - * - * This function get the union of the rectangles @p dst and @p src. The - * result is stored in @p dst. No check is done on @p dst or @p src, - * so they must be valid rectangles. - */ -static inline void -eina_rectangle_union(Eina_Rectangle *dst, const Eina_Rectangle *src) -{ - /* left */ - if (dst->x > src->x) - { - dst->w += dst->x - src->x; - dst->x = src->x; - } - /* right */ - if ((dst->x + dst->w) < (src->x + src->w)) - dst->w = src->x + src->w; - /* top */ - if (dst->y > src->y) - { - dst->h += dst->y - src->y; - dst->y = src->y; - } - /* bottom */ - if ((dst->y + dst->h) < (src->y + src->h)) - dst->h = src->y + src->h; -} - -/** - * @brief Get the intersection of two rectangles. - * - * @param dst The first rectangle. - * @param src The second rectangle. - * @return #EINA_TRUE if the rectangles intersect, #EINA_FALSE - * otherwise. - * - * This function get the intersection of the rectangles @p dst and - * @p src. The result is stored in @p dst. No check is done on @p dst - * or @p src, so they must be valid rectangles. - */ -static inline Eina_Bool -eina_rectangle_intersection(Eina_Rectangle *dst, const Eina_Rectangle *src) -{ - if (!(eina_rectangles_intersect(dst, src))) - return EINA_FALSE; - - /* left */ - if (dst->x < src->x) - { - dst->w += dst->x - src->x; - dst->x = src->x; - if (dst->w < 0) - dst->w = 0; - } - /* right */ - if ((dst->x + dst->w) > (src->x + src->w)) - dst->w = src->x + src->w - dst->x; - /* top */ - if (dst->y < src->y) - { - dst->h += dst->y - src->y; - dst->y = src->y; - if (dst->h < 0) - dst->h = 0; - } - /* bottom */ - if ((dst->y + dst->h) > (src->y + src->h)) - dst->h = src->y + src->h - dst->y; - - return EINA_TRUE; -} - -static inline void -eina_rectangle_rescale_in(const Eina_Rectangle *out, const Eina_Rectangle *in, Eina_Rectangle *res) -{ - res->x = in->x - out->x; - res->y = in->y - out->y; - res->w = in->w; - res->h = in->h; -} - -static inline void -eina_rectangle_rescale_out(const Eina_Rectangle *out, const Eina_Rectangle *in, Eina_Rectangle *res) -{ - res->x = out->x + in->x; - res->y = out->y + in->y; - res->w = out->w; - res->h = out->h; -} - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_str.x b/tests/suite/ecore/src/include/eina_inline_str.x deleted file mode 100644 index a9d8579217..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_str.x +++ /dev/null @@ -1,76 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_STR_INLINE_H_ -#define EINA_STR_INLINE_H_ - -/** - * @addtogroup Eina_String_Group String - * - * @{ - */ - -/** - * @brief Count up to a given amount of bytes of the given string. - * - * @param str The string pointer. - * @param maxlen The maximum length to allow. - * @return the string size or (size_t)-1 if greater than @a maxlen. - * - * This function returns the size of @p str, up to @p maxlen - * characters. It avoid needless iterations after that size. @p str - * must be a valid pointer and MUST not be @c NULL, otherwise this - * function will crash. This function returns the string size, or - * (size_t)-1 if the size is greater than @a maxlen. - */ -static inline size_t -eina_strlen_bounded(const char *str, size_t maxlen) -{ - const char *itr, *str_maxend = str + maxlen; - for (itr = str; *itr != '\0'; itr++) - if (itr == str_maxend) return (size_t)-1; - return itr - str; -} - -/** - * @brief Join two strings of known length. - * - * @param dst The buffer to store the result. - * @param size Size (in byte) of the buffer. - * @param sep The separator character to use. - * @param a First string to use, before @p sep. - * @param b Second string to use, after @p sep. - * @return The number of characters printed. - * - * This function is similar to eina_str_join_len(), but will compute - * the length of @p a and @p b using strlen(). - * - * @see eina_str_join_len() - * @see eina_str_join_static() - */ -static inline size_t -eina_str_join(char *dst, size_t size, char sep, const char *a, const char *b) -{ - return eina_str_join_len(dst, size, sep, a, strlen(a), b, strlen(b)); -} - -/** - * @} - */ - -#endif /* EINA_STR_INLINE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_inline_stringshare.x b/tests/suite/ecore/src/include/eina_inline_stringshare.x deleted file mode 100644 index 236c227416..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_stringshare.x +++ /dev/null @@ -1,91 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_STRINGSHARE_INLINE_H_ -#define EINA_STRINGSHARE_INLINE_H_ - -#include <string.h> -#include "eina_stringshare.h" -/** - * @addtogroup Eina_Stringshare_Group Stringshare - * - * @{ - */ - -/** - * Replace the previously stringshared pointer with new content. - * - * The string pointed by @a p_str should be previously stringshared or - * @c NULL and it will be eina_stringshare_del(). The new string will - * be passed to eina_stringshare_add() and then assigned to @c *p_str. - * - * @param p_str pointer to the stringhare to be replaced. Must not be - * @c NULL, but @c *p_str may be @c NULL as it is a valid - * stringshare handle. - * @param news new string to be stringshared, may be @c NULL. - * - * @return #EINA_TRUE if the strings were different and thus replaced, - * #EINA_FALSE if the strings were the same after shared. - */ -static inline Eina_Bool -eina_stringshare_replace(const char **p_str, const char *news) -{ - if (*p_str == news) return EINA_FALSE; - - news = eina_stringshare_add(news); - eina_stringshare_del(*p_str); - if (*p_str == news) - return EINA_FALSE; - *p_str = news; - return EINA_TRUE; -} - -/** - * Replace the previously stringshared pointer with a new content. - * - * The string pointed by @a p_str should be previously stringshared or - * @c NULL and it will be eina_stringshare_del(). The new string will - * be passed to eina_stringshare_add_length() and then assigned to @c *p_str. - * - * @param p_str pointer to the stringhare to be replaced. Must not be - * @c NULL, but @c *p_str may be @c NULL as it is a valid - * stringshare handle. - * @param news new string to be stringshared, may be @c NULL. - * @param slen The string size (<= strlen(str)). - * - * @return #EINA_TRUE if the strings were different and thus replaced, - * #EINA_FALSE if the strings were the same after shared. - */ -static inline Eina_Bool -eina_stringshare_replace_length(const char **p_str, const char *news, unsigned int slen) -{ - if (*p_str == news) return EINA_FALSE; - - news = eina_stringshare_add_length(news, slen); - eina_stringshare_del(*p_str); - if (*p_str == news) - return EINA_FALSE; - *p_str = news; - return EINA_TRUE; -} - -/** - * @} - */ - -#endif /* EINA_STRINGSHARE_INLINE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_inline_tiler.x b/tests/suite/ecore/src/include/eina_inline_tiler.x deleted file mode 100644 index 9919339386..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_tiler.x +++ /dev/null @@ -1,182 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_TILER_INLINE_H_ -#define EINA_TILER_INLINE_H_ - -#include "eina_safety_checks.h" - -/** - * @cond LOCAL - * This struct should not be accessed directly, it is used by - * eina_tile_grid_slicer functions to maintain context and fill "info" - * member with correct values for given iteration. - */ -struct _Eina_Tile_Grid_Slicer -{ - unsigned long col1, col2, row1, row2; // initial and final col,row - int tile_w, tile_h; // tile width, height - int x_rel, y_rel; // starting x,y coordinates of the first col,row - int w1_rel, h1_rel; // width,height of the first col,row - int w2_rel, h2_rel; // width,height of the last col,row - struct Eina_Tile_Grid_Info info; // info about the current tile - Eina_Bool first; -}; - -/** - * @endcond - */ - -/** - * @brief Iterates over the tiles set by eina_tile_grid_slicer_setup(). - * - * @param slc Pointer to an Eina_Tile_Grid_Slicer struct. - * @param rect Pointer to a struct Eina_Tile_Grid_Info *. - * @return @c EINA_TRUE if the current rect is valid. - * @c EINA_FALSE if there is no more rects to iterate over (and - * thus the current one isn't valid). - * - * This functions iterates over each Eina_Tile_Grid_Info *rect of the grid. - * eina_tile_grid_slicer_setup() must be called first, and *rect is only valid - * if this function returns EINA_TRUE. Its content shouldn't be modified. - */ -static inline Eina_Bool -eina_tile_grid_slicer_next(Eina_Tile_Grid_Slicer *slc, const Eina_Tile_Grid_Info **rect) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(slc, 0); - - if (slc->first) - { - slc->first = 0; - *rect = &slc->info; - return EINA_TRUE; - } - - slc->info.col++; - - if (slc->info.col > slc->col2) - { - slc->info.row++; - if (slc->info.row > slc->row2) - return EINA_FALSE; - else if (slc->info.row < slc->row2) - slc->info.rect.h = slc->tile_h; - else - slc->info.rect.h = slc->h2_rel; - slc->info.rect.y = 0; - slc->info.col = slc->col1; - slc->info.rect.x = slc->x_rel; - slc->info.rect.w = slc->w1_rel; - } - else - { - slc->info.rect.x = 0; - if (slc->info.col < slc->col2) - slc->info.rect.w = slc->tile_w; - else - slc->info.rect.w = slc->w2_rel; - } - - if (slc->info.rect.w == slc->tile_w && slc->info.rect.h == slc->tile_h) - slc->info.full = EINA_TRUE; - else - slc->info.full = EINA_FALSE; - - *rect = &slc->info; - - return EINA_TRUE; -} - -/** - * @brief Setup an Eina_Tile_Grid_Slicer struct. - * - * @param slc Pointer to an Eina_Tile_Grid_Slicer struct. - * @param x X axis coordinate. - * @param y Y axis coordinate. - * @param w width. - * @param h height. - * @param tile_w tile width. - * @param tile_h tile height. - * @return A pointer to the Eina_Iterator. - * @c NULL on failure. - * - * This function splits the rectangle given as argument into tiles of size - * tile_w X tile_h, and returns an iterator to them. The geometry of each - * tile can be accessed with eina_tile_grid_slicer_next, where rect - * will be a pointer to a struct Eina_Tile_Grid_Info. - */ -static inline Eina_Bool -eina_tile_grid_slicer_setup(Eina_Tile_Grid_Slicer *slc, int x, int y, int w, int h, int tile_w, int tile_h) -{ - int tx1, tx2, ty1, ty2; - - EINA_SAFETY_ON_NULL_RETURN_VAL(slc, 0); - - tx1 = x; - ty1 = y; - tx2 = x + w - 1; - ty2 = y + h - 1; - - if (x < 0 || y < 0 || w <= 0 || h <= 0 || tile_w <= 0 || tile_h <= 0) - { - slc->first = 0; - slc->col1 = slc->row1 = 0; - slc->col2 = slc->row2 = 0; - slc->info.col = slc->col1; - slc->info.row = slc->row1; - return EINA_TRUE; - } - - slc->col1 = tx1 / tile_w; - slc->row1 = ty1 / tile_h; - slc->col2 = (tx2 - 0) / tile_w; - slc->row2 = (ty2 - 0) / tile_h; - slc->x_rel = tx1 % tile_w; - slc->y_rel = ty1 % tile_h; - slc->w1_rel = tile_w - slc->x_rel; - slc->h1_rel = tile_h - slc->y_rel; - slc->w2_rel = tx2 % tile_w + 1; - slc->h2_rel = ty2 % tile_h + 1; - - slc->tile_w = tile_w; - slc->tile_h = tile_h; - - slc->first = 1; - slc->info.col = slc->col1; - slc->info.row = slc->row1; - slc->info.rect.x = slc->x_rel; - slc->info.rect.y = slc->y_rel; - - if (slc->info.col == slc->col2) - slc->w1_rel = slc->w2_rel - slc->x_rel; - - if (slc->info.row == slc->row2) - slc->h1_rel = slc->h2_rel - slc->y_rel; - - slc->info.rect.w = slc->w1_rel; - slc->info.rect.h = slc->h1_rel; - - if (slc->info.rect.w == slc->tile_w && slc->info.rect.h == slc->tile_h) - slc->info.full = EINA_TRUE; - else - slc->info.full = EINA_FALSE; - - return EINA_TRUE; -} - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_trash.x b/tests/suite/ecore/src/include/eina_inline_trash.x deleted file mode 100644 index 0fa78ce631..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_trash.x +++ /dev/null @@ -1,90 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLINE_TRASH_X__ -#define EINA_INLINE_TRASH_X__ - -/** - * @brief Initialize a trash before using it. - * - * @param trash The trash. - * - * This function just set to zero the trash to correctly - * initialize it. - * - * @note You can just set *trash to NULL and you will have - * the same result. - */ -static inline void -eina_trash_init(Eina_Trash **trash) -{ - *trash = NULL; -} - -/** - * @brief Push an unused pointer in the trash instead of freeing it. - * - * @param trash A pointer to an Eina_Trash. - * @param data An unused pointer big enougth to put a (void*). - * - * Instead of freeing a pointer and put pressure on malloc/free - * you can push it in a trash for a later use. This function just - * provide a fast way to push a now unused pointer into a trash. - * - * @note Do never use the pointer after insertion or bad things will - * happens. - * - * @note This trash will not resize, nor do anything with the size of - * the region pointed by @p data, so it's your duty to manage the size. - */ -static inline void -eina_trash_push(Eina_Trash **trash, void *data) -{ - Eina_Trash *tmp; - - tmp = (Eina_Trash *)data; - tmp->next = *trash; - *trash = tmp; -} - -/** - * @brief Pop an available pointer from the trash if possible. - * - * @param trash A pointer to an Eina_Trash. - * - * Instead of calling malloc, and putting pressure on malloc/free - * you can recycle the content of the trash, if it's not empty. - * - * @note This trash will not resize, nor do anything with the size of - * the region pointed by pointer inside the trash, so it's your duty - * to manage the size of the returned pointer. - */ -static inline void* -eina_trash_pop(Eina_Trash **trash) -{ - void *tmp; - - tmp = *trash; - - if (*trash) - *trash = (*trash)->next; - - return tmp; -} - -#endif diff --git a/tests/suite/ecore/src/include/eina_inline_ustringshare.x b/tests/suite/ecore/src/include/eina_inline_ustringshare.x deleted file mode 100644 index c2e13e003d..0000000000 --- a/tests/suite/ecore/src/include/eina_inline_ustringshare.x +++ /dev/null @@ -1,93 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Gustavo Sverzut Barbieri - Tom Hacohen - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_USTRINGSHARE_INLINE_H_ -#define EINA_USTRINGSHARE_INLINE_H_ - -#include "eina_unicode.h" -#include "eina_ustringshare.h" - -/** - * @addtogroup Eina_UStringshare_Group Unicode Stringshare - * - * @{ - */ - -/** - * Replace the previously stringshared pointer with new content. - * - * The string pointed by @a p_str should be previously stringshared or - * @c NULL and it will be eina_ustringshare_del(). The new string will - * be passed to eina_ustringshare_add() and then assigned to @c *p_str. - * - * @param p_str pointer to the stringhare to be replaced. Must not be - * @c NULL, but @c *p_str may be @c NULL as it is a valid - * stringshare handle. - * @param news new string to be stringshared, may be @c NULL. - * - * @return #EINA_TRUE if the strings were different and thus replaced, - * #EINA_FALSE if the strings were the same after shared. - */ -static inline Eina_Bool -eina_ustringshare_replace(const Eina_Unicode **p_str, const Eina_Unicode *news) -{ - if (*p_str == news) return EINA_FALSE; - - news = eina_ustringshare_add(news); - eina_ustringshare_del(*p_str); - if (*p_str == news) - return EINA_FALSE; - *p_str = news; - return EINA_TRUE; -} - -/** - * Replace the previously stringshared pointer with a new content. - * - * The string pointed by @a p_str should be previously stringshared or - * @c NULL and it will be eina_ustringshare_del(). The new string will - * be passed to eina_ustringshare_add_length() and then assigned to @c *p_str. - * - * @param p_str pointer to the stringhare to be replaced. Must not be - * @c NULL, but @c *p_str may be @c NULL as it is a valid - * stringshare handle. - * @param news new string to be stringshared, may be @c NULL. - * @param slen The string size (<= strlen(str)). - * - * @return #EINA_TRUE if the strings were different and thus replaced, - * #EINA_FALSE if the strings were the same after shared. - */ -static inline Eina_Bool -eina_ustringshare_replace_length(const Eina_Unicode **p_str, const Eina_Unicode *news, unsigned int slen) -{ - if (*p_str == news) return EINA_FALSE; - - news = eina_ustringshare_add_length(news, slen); - eina_ustringshare_del(*p_str); - if (*p_str == news) - return EINA_FALSE; - *p_str = news; - return EINA_TRUE; -} - -/** - * @} - */ - -#endif /* EINA_USTRINGSHARE_INLINE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_inlist.h b/tests/suite/ecore/src/include/eina_inlist.h deleted file mode 100644 index 793354f376..0000000000 --- a/tests/suite/ecore/src/include/eina_inlist.h +++ /dev/null @@ -1,139 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Vincent Torri - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_INLIST_H_ -#define EINA_INLIST_H_ - -#include "eina_types.h" -#include "eina_iterator.h" -#include "eina_accessor.h" -#include <stddef.h> - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_Inline_List_Group Inline List - * - * @{ - */ - -/** - * @typedef Eina_Inlist - * Inlined list type. - */ -typedef struct _Eina_Inlist Eina_Inlist; - -/** - * @struct _Eina_Inlist - * Inlined list type. - */ -struct _Eina_Inlist { - Eina_Inlist *next; - /**< next node */ - Eina_Inlist *prev; - /**< previous node */ - Eina_Inlist *last; - /**< last node */ -}; - -#define EINA_INLIST Eina_Inlist __in_list -#define EINA_INLIST_GET(Inlist) (& ((Inlist)->__in_list)) -#define EINA_INLIST_CONTAINER_GET(ptr, \ - type) ((type *)((char *)ptr - \ - offsetof(type, __in_list))) - -EAPI Eina_Inlist *eina_inlist_append(Eina_Inlist * in_list, - Eina_Inlist * - in_item) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_Inlist *eina_inlist_prepend(Eina_Inlist * in_list, - Eina_Inlist * - in_item) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_Inlist *eina_inlist_append_relative(Eina_Inlist * in_list, - Eina_Inlist * in_item, - Eina_Inlist * - in_relative) -EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Inlist *eina_inlist_prepend_relative(Eina_Inlist * in_list, - Eina_Inlist * in_item, - Eina_Inlist * - in_relative) -EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Inlist *eina_inlist_remove(Eina_Inlist * in_list, - Eina_Inlist * - in_item) EINA_ARG_NONNULL(1, - 2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_Inlist *eina_inlist_find(Eina_Inlist * in_list, - Eina_Inlist * - in_item) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_Inlist *eina_inlist_promote(Eina_Inlist * list, - Eina_Inlist * - item) EINA_ARG_NONNULL(1, - 2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_Inlist *eina_inlist_demote(Eina_Inlist * list, - Eina_Inlist * - item) EINA_ARG_NONNULL(1, - 2) - EINA_WARN_UNUSED_RESULT; -EAPI unsigned int eina_inlist_count(const Eina_Inlist * - list) EINA_WARN_UNUSED_RESULT; - -EAPI Eina_Iterator *eina_inlist_iterator_new(const Eina_Inlist * in_list) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI Eina_Accessor *eina_inlist_accessor_new(const Eina_Inlist * in_list) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; - -/* This two macros are helpers for the _FOREACH ones, don't use them */ -#define _EINA_INLIST_OFFSET(ref) ((char *)&(ref)->__in_list - (char *)(ref)) -#define _EINA_INLIST_CONTAINER(ref, ptr) (void *)((char *)(ptr) - \ - _EINA_INLIST_OFFSET(ref)) - -#define EINA_INLIST_FOREACH(list, l) \ - for (l = NULL, l = (list ? _EINA_INLIST_CONTAINER(l, list) : NULL); l; \ - l = (EINA_INLIST_GET(l)->next ? _EINA_INLIST_CONTAINER(l, EINA_INLIST_GET(l)->next) : NULL)) -#define EINA_INLIST_REVERSE_FOREACH(list, l) \ - for (l = NULL, l = (list ? _EINA_INLIST_CONTAINER(l, list->last) : NULL); \ - l; l = (EINA_INLIST_GET(l)->prev ? _EINA_INLIST_CONTAINER(l, EINA_INLIST_GET(l)->prev) : NULL)) - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /*EINA_INLIST_H_ */ diff --git a/tests/suite/ecore/src/include/eina_iterator.h b/tests/suite/ecore/src/include/eina_iterator.h deleted file mode 100644 index ad5d00c53b..0000000000 --- a/tests/suite/ecore/src/include/eina_iterator.h +++ /dev/null @@ -1,149 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_ITERATOR_H__ -#define EINA_ITERATOR_H__ - -#include "eina_config.h" - -#include "eina_types.h" -#include "eina_magic.h" - -/** - * @addtogroup Eina_Content_Access_Group Content Access - * - * @{ - */ - -/** - * @defgroup Eina_Iterator_Group Iterator Functions - * - * @{ - */ - -/** - * @typedef Eina_Iterator - * Type for iterators. - */ -typedef struct _Eina_Iterator Eina_Iterator; - -typedef Eina_Bool(*Eina_Iterator_Next_Callback) (Eina_Iterator * it, - void **data); -typedef void *(*Eina_Iterator_Get_Container_Callback) (Eina_Iterator * it); -typedef void (*Eina_Iterator_Free_Callback) (Eina_Iterator * it); -typedef Eina_Bool(*Eina_Iterator_Lock_Callback) (Eina_Iterator * it); - -struct _Eina_Iterator { -#define EINA_ITERATOR_VERSION 1 - int version; - - Eina_Iterator_Next_Callback next EINA_ARG_NONNULL(1, - 2) - EINA_WARN_UNUSED_RESULT; - Eina_Iterator_Get_Container_Callback get_container - EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; - Eina_Iterator_Free_Callback free EINA_ARG_NONNULL(1); - - Eina_Iterator_Lock_Callback lock EINA_WARN_UNUSED_RESULT; - Eina_Iterator_Lock_Callback unlock EINA_WARN_UNUSED_RESULT; - -#define EINA_MAGIC_ITERATOR 0x98761233 - EINA_MAGIC}; - - -#define FUNC_ITERATOR_NEXT(Function) ((Eina_Iterator_Next_Callback)Function) -#define FUNC_ITERATOR_GET_CONTAINER(Function) (( \ - Eina_Iterator_Get_Container_Callback) \ - Function) -#define FUNC_ITERATOR_FREE(Function) ((Eina_Iterator_Free_Callback)Function) -#define FUNC_ITERATOR_LOCK(Function) ((Eina_Iterator_Lock_Callback)Function) - -EAPI void eina_iterator_free(Eina_Iterator * iterator) EINA_ARG_NONNULL(1); - -EAPI void *eina_iterator_container_get(Eina_Iterator * - iterator) EINA_ARG_NONNULL(1) - EINA_PURE; -EAPI Eina_Bool eina_iterator_next(Eina_Iterator * iterator, - void **data) EINA_ARG_NONNULL(1, - 2) - EINA_WARN_UNUSED_RESULT; - -EAPI void eina_iterator_foreach(Eina_Iterator * iterator, - Eina_Each_Cb callback, - const void *fdata) EINA_ARG_NONNULL(1, 2); - -EAPI Eina_Bool eina_iterator_lock(Eina_Iterator * - iterator) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_iterator_unlock(Eina_Iterator * - iterator) EINA_ARG_NONNULL(1); - -/** - * @def EINA_ITERATOR_FOREACH - * @brief Macro to iterate over all elements easily. - * - * @param itr The iterator to use. - * @param data Where to store * data, must be a pointer support getting - * its address since * eina_iterator_next() requires a pointer - * to pointer! - * - * This macro is a convenient way to use iterators, very similar to - * EINA_LIST_FOREACH(). - * - * This macro can be used for freeing the data of a list, like in the - * following example. It has the same goal as the one documented in - * EINA_LIST_FOREACH(), but using iterators: - * - * @code - * Eina_List *list; - * Eina_Iterator *itr; - * char *data; - * - * // list is already filled, - * // its elements are just duplicated strings - * - * itr = eina_list_iterator_new(list); - * EINA_ITERATOR_FOREACH(itr, data) - * free(data); - * eina_iterator_free(itr); - * eina_list_free(list); - * @endcode - * - * @note this example is not optimal algorithm to release a list since - * it will walk the list twice, but it serves as an example. For - * optimized version use EINA_LIST_FREE() - * - * @warning unless explicitly stated in functions returning iterators, - * do not modify the iterated object while you walk it, in this - * example using lists, do not remove list nodes or you might - * crash! This is not a limitiation of iterators themselves, - * rather in the iterators implementations to keep them as simple - * and fast as possible. - */ -#define EINA_ITERATOR_FOREACH(itr, \ - data) while (eina_iterator_next((itr), \ - (void **)&(data))) - -/** - * @} - */ - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_lalloc.h b/tests/suite/ecore/src/include/eina_lalloc.h deleted file mode 100644 index 260bcf5097..0000000000 --- a/tests/suite/ecore/src/include/eina_lalloc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_LALLOC_H_ -#define EINA_LALLOC_H_ - -#include "eina_types.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Lalloc_Group Lazy allocator - * - * @{ - */ - -typedef Eina_Bool(*Eina_Lalloc_Alloc) (void *user_data, int num); -#define EINA_LALLOC_ALLOC(function) ((Eina_Lalloc_Alloc)function) -typedef void (*Eina_Lalloc_Free) (void *user_data); -#define EINA_LALLOC_FREE(function) ((Eina_Lalloc_Free)function) - -typedef struct _Eina_Lalloc Eina_Lalloc; - -EAPI Eina_Lalloc *eina_lalloc_new(void *data, - Eina_Lalloc_Alloc alloc_cb, - Eina_Lalloc_Free free_cb, - int num_init) EINA_ARG_NONNULL(2, 3); -EAPI void eina_lalloc_free(Eina_Lalloc * a) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_lalloc_elements_add(Eina_Lalloc * a, - int num) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_lalloc_element_add(Eina_Lalloc * - a) EINA_ARG_NONNULL(1); - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_LALLOC_H_ */ diff --git a/tests/suite/ecore/src/include/eina_list.h b/tests/suite/ecore/src/include/eina_list.h deleted file mode 100644 index 3a03e73619..0000000000 --- a/tests/suite/ecore/src/include/eina_list.h +++ /dev/null @@ -1,413 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Vincent Torri, Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_LIST_H_ -#define EINA_LIST_H_ - -#include <stdlib.h> - -#include "eina_config.h" - -#include "eina_types.h" -#include "eina_iterator.h" -#include "eina_accessor.h" -#include "eina_magic.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_List_Group List - * - * @{ - */ - -/** - * @typedef Eina_List - * Type for a generic double linked list. - */ -typedef struct _Eina_List Eina_List; - -typedef struct _Eina_List_Accounting Eina_List_Accounting; - -/** - * @struct _Eina_List - * Type for a generic double linked list. - */ -struct _Eina_List { - void *data; - /**< Pointer to list element payload */ - Eina_List *next; - /**< Next member in the list */ - Eina_List *prev; - /**< Previous member in the list */ - Eina_List_Accounting *accounting; - /**< Private list accounting info - don't touch */ - - EINA_MAGIC}; - -struct _Eina_List_Accounting { - Eina_List *last; - unsigned int count; - EINA_MAGIC}; - -EAPI Eina_List *eina_list_append(Eina_List * list, - const void *data) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_prepend(Eina_List * list, - const void *data) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_append_relative(Eina_List * list, - const void *data, - const void *relative) -EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_append_relative_list(Eina_List * list, - const void *data, - Eina_List * - relative) -EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_prepend_relative(Eina_List * list, - const void *data, - const void *relative) -EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_prepend_relative_list(Eina_List * list, - const void *data, - Eina_List * - relative) -EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_sorted_insert(Eina_List * list, - Eina_Compare_Cb func, - const void *data) -EINA_ARG_NONNULL(2, 3) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_remove(Eina_List * list, - const void *data) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_remove_list(Eina_List * list, - Eina_List * - remove_list) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_promote_list(Eina_List * list, - Eina_List * - move_list) EINA_ARG_NONNULL(2) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_demote_list(Eina_List * list, - Eina_List * move_list); -EAPI void *eina_list_data_find(const Eina_List * list, const void *data) -EINA_PURE EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_data_find_list(const Eina_List * list, - const void *data) -EINA_PURE EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_free(Eina_List * list); -EAPI void *eina_list_nth(const Eina_List * list, unsigned int n) -EINA_PURE EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_nth_list(const Eina_List * list, unsigned int n) -EINA_PURE EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_reverse(Eina_List * - list) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_reverse_clone(const Eina_List * - list) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_clone(const Eina_List * - list) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_sort(Eina_List * list, unsigned int size, - Eina_Compare_Cb func) EINA_ARG_NONNULL(3) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_merge(Eina_List * left, - Eina_List * right) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_sorted_merge(Eina_List * left, Eina_List * right, - Eina_Compare_Cb func) -EINA_ARG_NONNULL(3) EINA_WARN_UNUSED_RESULT; -EAPI Eina_List *eina_list_split_list(Eina_List * list, - Eina_List * relative, - Eina_List ** - right) EINA_WARN_UNUSED_RESULT; - - -EAPI Eina_List *eina_list_search_sorted_near_list(const Eina_List * list, - Eina_Compare_Cb func, - const void *data, - int *result_cmp); -EAPI Eina_List *eina_list_search_sorted_list(const Eina_List * list, - Eina_Compare_Cb func, - const void *data); -EAPI void *eina_list_search_sorted(const Eina_List * list, - Eina_Compare_Cb func, const void *data); -EAPI Eina_List *eina_list_search_unsorted_list(const Eina_List * list, - Eina_Compare_Cb func, - const void *data); -EAPI void *eina_list_search_unsorted(const Eina_List * list, - Eina_Compare_Cb func, - const void *data); - -static inline Eina_List *eina_list_last(const Eina_List * list) -EINA_PURE EINA_WARN_UNUSED_RESULT; -static inline Eina_List *eina_list_next(const Eina_List * list) -EINA_PURE EINA_WARN_UNUSED_RESULT; -static inline Eina_List *eina_list_prev(const Eina_List * list) -EINA_PURE EINA_WARN_UNUSED_RESULT; -static inline void *eina_list_data_get(const Eina_List * list) -EINA_PURE EINA_WARN_UNUSED_RESULT; -static inline unsigned int eina_list_count(const Eina_List * - list) EINA_PURE; - -EAPI Eina_Iterator *eina_list_iterator_new(const Eina_List * list) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI Eina_Iterator *eina_list_iterator_reversed_new(const Eina_List * list) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI Eina_Accessor *eina_list_accessor_new(const Eina_List * list) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; - -/** - * @def EINA_LIST_FOREACH - * @brief Macro to iterate over a list. - * - * @param list The list to iterate over. - * @param l A list that is used as an iterator and points to the current node. - * @param data Current item's data. - * - * This macro iterates over @p list from the first element to - * the last. @p data is the data related to the current element. - * @p l is an #Eina_List used as the list iterator. - * - * It can be used to free list data, as in the following example: - * - * @code - * Eina_List *list; - * Eina_List *l; - * char *data; - * - * // list is already filled, - * // its elements are just duplicated strings, - * // EINA_LIST_FOREACH will be used to free those strings - * - * EINA_LIST_FOREACH(list, l, data) - * free(data); - * eina_list_free(list); - * @endcode - * - * @note This is not the optimal way to release memory allocated to - * a list, since it iterates over the list twice. - * For an optimized algorithm, use EINA_LIST_FREE(). - * - * @warning Be careful when deleting list nodes. - * If you remove the current node and continue iterating, - * the code will fail because the macro will not be able - * to get the next node. Notice that it's OK to remove any - * node if you stop the loop after that. - * For destructive operations such as this, consider - * using EINA_LIST_FOREACH_SAFE(). - */ -#define EINA_LIST_FOREACH(list, l, data) \ - for (l = list, \ - data = eina_list_data_get(l); \ - l; \ - l = eina_list_next(l), \ - data = eina_list_data_get(l)) - -/** - * @def EINA_LIST_REVERSE_FOREACH - * @brief Macro to iterate over a list in the reverse order. - * - * @param list The list to iterate over. - * @param l A list that is used as an iterator and points to the current node. - * @param data Current item's data. - * - * This macro works like EINA_LIST_FOREACH, but iterates from the - * last element of a list to the first. - * @p data is the data related to the current element, while @p l - * is an #Eina_List that is used as the list iterator. - * - * It can be used to free list data, as in the following example: - * - * @code - * Eina_List *list; - * Eina_List *l; - * char *data; - * - * // list is already filled, - * // its elements are just duplicated strings, - * // EINA_LIST_REVERSE_FOREACH will be used to free those strings - * - * EINA_LIST_REVERSE_FOREACH(list, l, data) - * free(data); - * eina_list_free(list); - * @endcode - * - * @note This is not the optimal way to release memory allocated to - * a list, since it iterates over the list twice. - * For an optimized algorithm, use EINA_LIST_FREE(). - * - * @warning Be careful when deleting list nodes. - * If you remove the current node and continue iterating, - * the code will fail because the macro will not be able - * to get the next node. Notice that it's OK to remove any - * node if you stop the loop after that. - * For destructive operations such as this, consider - * using EINA_LIST_REVERSE_FOREACH_SAFE(). - */ -#define EINA_LIST_REVERSE_FOREACH(list, l, data) \ - for (l = eina_list_last(list), \ - data = eina_list_data_get(l); \ - l; \ - l = eina_list_prev(l), \ - data = eina_list_data_get(l)) - -/** - * @def EINA_LIST_FOREACH_SAFE - * @brief Macro to iterate over a list with support for node deletion. - * - * @param list The list to iterate over. - * @param l A list that is used as an iterator and points to the current node. - * @param l_next A list that is used as an iterator and points to the next node. - * @param data Current item's data. - * - * This macro iterates over @p list from the first element to - * the last. @p data is the data related to the current element. - * @p l is an #Eina_List used as the list iterator. - * - * Since this macro stores a pointer to the next list node in @p l_next, - * deleting the current node and continuing looping is safe. - * - * This macro can be used to free list nodes, as in the following example: - * - * @code - * Eina_List *list; - * Eina_List *l; - * Eina_List *l_next; - * char *data; - * - * // list is already filled, - * // its elements are just duplicated strings, - * // EINA_LIST_FOREACH_SAFE will be used to free elements that match "key". - * - * EINA_LIST_FOREACH_SAFE(list, l, l_next, data) - * if (strcmp(data, "key") == 0) { - * free(data); - * list = eina_list_remove_list(list, l); - * } - * @endcode - */ -#define EINA_LIST_FOREACH_SAFE(list, l, l_next, data) \ - for (l = list, \ - l_next = eina_list_next(l), \ - data = eina_list_data_get(l); \ - l; \ - l = l_next, \ - l_next = eina_list_next(l), \ - data = eina_list_data_get(l)) - -/** - * @def EINA_LIST_REVERSE_FOREACH_SAFE - * @brief Macro to iterate over a list in the reverse order with support - * for deletion. - * - * @param list The list to iterate over. - * @param l A list that is used as an iterator and points to the current node. - * @param l_prev A list that is used as an iterator and points to the previous node. - * @param data Current item's data. - * - * This macro works like EINA_LIST_FOREACH_SAFE, but iterates from the - * last element of a list to the first. - * @p data is the data related to the current element, while @p l - * is an #Eina_List that is used as the list iterator. - * - * Since this macro stores a pointer to the previous list node in @p l_prev, - * deleting the current node and continuing looping is safe. - * - * This macro can be used to free list nodes, as in the following example: - * - * @code - * Eina_List *list; - * Eina_List *l; - * Eina_List *l_prev; - * char *data; - * - * // list is already filled, - * // its elements are just duplicated strings, - * // EINA_LIST_REVERSE_FOREACH_SAFE will be used to free elements that match "key". - * - * EINA_LIST_REVERSE_FOREACH_SAFE(list, l, l_prev, data) - * if (strcmp(data, "key") == 0) { - * free(data); - * list = eina_list_remove_list(list, l); - * } - * @endcode - */ -#define EINA_LIST_REVERSE_FOREACH_SAFE(list, l, l_prev, data) \ - for (l = eina_list_last(list), \ - l_prev = eina_list_prev(l), \ - data = eina_list_data_get(l); \ - l; \ - l = l_prev, \ - l_prev = eina_list_prev(l), \ - data = eina_list_data_get(l)) - -/** - * @def EINA_LIST_FREE - * @brief Macro to remove each list node while having access to each node's data. - * - * @param list The list that will be cleared. - * @param data Current node's data. - * - * This macro will call #eina_list_remove_list for each list node, and store - * the data contained in the current node in @p data. - * - * If you do not need to release node data, it is easier to call #eina_list_free(). - * - * @code - * Eina_List *list; - * char *data; - * - * // list is already filled, - * // its elements are just duplicated strings, - * - * EINA_LIST_FREE(list, data) - * free(data); - * @endcode - * - * @see eina_list_free() - */ -#define EINA_LIST_FREE(list, data) \ - for (data = eina_list_data_get(list); \ - list; \ - list = eina_list_remove_list(list, list), \ - data = eina_list_data_get(list)) - -#include "eina_inline_list.x" - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_LIST_H_ */ diff --git a/tests/suite/ecore/src/include/eina_log.h b/tests/suite/ecore/src/include/eina_log.h deleted file mode 100644 index af0566951a..0000000000 --- a/tests/suite/ecore/src/include/eina_log.h +++ /dev/null @@ -1,381 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_LOG_H_ -#define EINA_LOG_H_ - -#include <stdlib.h> -#include <stdarg.h> - -#include "eina_types.h" - -#define EINA_COLOR_LIGHTRED "\033[31;1m" -#define EINA_COLOR_RED "\033[31m" -#define EINA_COLOR_LIGHTBLUE "\033[34;1m" -#define EINA_COLOR_BLUE "\033[34m" -#define EINA_COLOR_GREEN "\033[32;1m" -#define EINA_COLOR_YELLOW "\033[33;1m" -#define EINA_COLOR_ORANGE "\033[0;33m" -#define EINA_COLOR_WHITE "\033[37;1m" -#define EINA_COLOR_LIGHTCYAN "\033[36;1m" -#define EINA_COLOR_CYAN "\033[36m" -#define EINA_COLOR_RESET "\033[0m" -#define EINA_COLOR_HIGH "\033[1m" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Log_Group Log - * - * @{ - */ - -/** - * EINA_LOG_DOMAIN_GLOBAL is the general purpose log domain to be - * used, it is always registered and available everywhere. - */ -EAPI extern int EINA_LOG_DOMAIN_GLOBAL; - -#ifndef EINA_LOG_DOMAIN_DEFAULT - -/** - * @def EINA_LOG_DOMAIN_DEFAULT - * This macro defines the domain to use with the macros EINA_LOG_DOM_DBG(), - * EINA_LOG_DOM_INFO(), EINA_LOG_DOM_WARN(), EINA_LOG_DOM_ERR() and - * EINA_LOG_DOM_CRIT(). - * - * If not defined prior to the inclusion of this header, then it - * defaults to #EINA_LOG_DOMAIN_GLOBAL. - * - * @note One may like to redefine this in its code to avoid typing too - * much. In this case the recommended way is: - * - * @code - * #include <Eina.h> - * #undef EINA_LOG_DOMAIN_DEFAULT - * #define EINA_LOG_DOMAIN_DEFAULT _log_dom - * static int _log_dom = -1; - * - * int main(void) - * { - * eina_init(); - * _log_dom = eina_log_domain_register("mydom", EINA_COLOR_CYAN); - * EINA_LOG_ERR("using my own domain"); - * return 0; - * } - * @endcode - * - * @warning If one defines the domain prior to inclusion of this - * header, the defined log domain symbol must be defined - * prior as well, otherwise the inlined functions defined by - * Eina will fail to find the symbol, causing build failure. - * - * @code - * #define EINA_LOG_DOMAIN_DEFAULT _log_dom - * static int _log_dom = -1; // must come before inclusion of Eina.h! - * #include <Eina.h> - * - * int main(void) - * { - * eina_init(); - * _log_dom = eina_log_domain_register("mydom", EINA_COLOR_CYAN); - * EINA_LOG_ERR("using my own domain"); - * return 0; - * } - * @endcode - * - */ -#define EINA_LOG_DOMAIN_DEFAULT EINA_LOG_DOMAIN_GLOBAL - -#endif /* EINA_LOG_DOMAIN_DEFAULT */ - - -/** - * @def EINA_LOG(DOM, LEVEL, fmt, ...) - * Logs a message on the specified domain, level and format. - * - * @note if @c EINA_LOG_LEVEL_MAXIMUM is defined, then messages larger - * than this value will be ignored regardless of current domain - * level, the eina_log_print() is not even called! Most - * compilers will just detect the two integers make the branch - * impossible and remove the branch and function call all - * together. Take this as optimization tip and possible remove - * debug messages from binaries to be deployed, saving on hot - * paths. Never define @c EINA_LOG_LEVEL_MAXIMUM on public - * header files. - */ -#ifdef EINA_LOG_LEVEL_MAXIMUM -#define EINA_LOG(DOM, LEVEL, fmt, ...) \ - do { \ - if (LEVEL <= EINA_LOG_LEVEL_MAXIMUM) { \ - eina_log_print(DOM, LEVEL, __FILE__, __FUNCTION__, __LINE__, \ - fmt, ## __VA_ARGS__); } \ - } while (0) -#else -#define EINA_LOG(DOM, LEVEL, fmt, ...) \ - eina_log_print(DOM, \ - LEVEL, \ - __FILE__, \ - __FUNCTION__, \ - __LINE__, \ - fmt, \ - ## __VA_ARGS__) -#endif - -/** - * @def EINA_LOG_DOM_CRIT(DOM, fmt, ...) - * Logs a message with level CRITICAL on the specified domain and format. - */ -#define EINA_LOG_DOM_CRIT(DOM, fmt, ...) \ - EINA_LOG(DOM, EINA_LOG_LEVEL_CRITICAL, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_DOM_ERR(DOM, fmt, ...) - * Logs a message with level ERROR on the specified domain and format. - */ -#define EINA_LOG_DOM_ERR(DOM, fmt, ...) \ - EINA_LOG(DOM, EINA_LOG_LEVEL_ERR, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_DOM_INFO(DOM, fmt, ...) - * Logs a message with level INFO on the specified domain and format. - */ -#define EINA_LOG_DOM_INFO(DOM, fmt, ...) \ - EINA_LOG(DOM, EINA_LOG_LEVEL_INFO, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_DOM_DBG(DOM, fmt, ...) - * Logs a message with level DEBUG on the specified domain and format. - */ -#define EINA_LOG_DOM_DBG(DOM, fmt, ...) \ - EINA_LOG(DOM, EINA_LOG_LEVEL_DBG, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_DOM_WARN(DOM, fmt, ...) - * Logs a message with level WARN on the specified domain and format. - */ -#define EINA_LOG_DOM_WARN(DOM, fmt, ...) \ - EINA_LOG(DOM, EINA_LOG_LEVEL_WARN, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_CRIT(fmt, ...) - * Logs a message with level CRITICAL on the default domain with the specified - * format. - */ -#define EINA_LOG_CRIT(fmt, ...) \ - EINA_LOG(EINA_LOG_DOMAIN_DEFAULT, \ - EINA_LOG_LEVEL_CRITICAL, \ - fmt, \ - ## __VA_ARGS__) - -/** - * @def EINA_LOG_ERR(fmt, ...) - * Logs a message with level ERROR on the default domain with the specified - * format. - */ -#define EINA_LOG_ERR(fmt, ...) \ - EINA_LOG(EINA_LOG_DOMAIN_DEFAULT, EINA_LOG_LEVEL_ERR, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_INFO(fmt, ...) - * Logs a message with level INFO on the default domain with the specified - * format. - */ -#define EINA_LOG_INFO(fmt, ...) \ - EINA_LOG(EINA_LOG_DOMAIN_DEFAULT, EINA_LOG_LEVEL_INFO, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_WARN(fmt, ...) - * Logs a message with level WARN on the default domain with the specified - * format. - */ -#define EINA_LOG_WARN(fmt, ...) \ - EINA_LOG(EINA_LOG_DOMAIN_DEFAULT, EINA_LOG_LEVEL_WARN, fmt, ## __VA_ARGS__) - -/** - * @def EINA_LOG_DBG(fmt, ...) - * Logs a message with level DEBUG on the default domain with the specified - * format. - */ -#define EINA_LOG_DBG(fmt, ...) \ - EINA_LOG(EINA_LOG_DOMAIN_DEFAULT, EINA_LOG_LEVEL_DBG, fmt, ## __VA_ARGS__) - -/** - * @typedef Eina_Log_Domain - * The domain used for logging. - */ -typedef struct _Eina_Log_Domain Eina_Log_Domain; - -/** - * @struct _Eina_Log_Domain - * The domain used for logging. - */ -struct _Eina_Log_Domain { - int level; - /**< Max level to log */ - const char *domain_str; - /**< Formatted string with color to print */ - const char *name; - /**< Domain name */ - size_t namelen; - /**< strlen(name) */ - - /* Private */ - Eina_Bool deleted:1; - /**< Flags deletion of domain, a free slot */ -}; - -EAPI void eina_log_threads_enable(void); - -/** - * @enum _Eina_Log_Level - * List of available logging levels. - */ -typedef enum _Eina_Log_Level { - EINA_LOG_LEVEL_CRITICAL, - /**< Critical log level */ - EINA_LOG_LEVEL_ERR, - /**< Error log level */ - EINA_LOG_LEVEL_WARN, - /**< Warning log level */ - EINA_LOG_LEVEL_INFO, - /**< Information log level */ - EINA_LOG_LEVEL_DBG, - /**< Debug log level */ - EINA_LOG_LEVELS, - /**< Count of default log levels */ - EINA_LOG_LEVEL_UNKNOWN = (-2147483647 - 1)/**< Unknown level */ -} Eina_Log_Level; - -/** - * @typedef Eina_Log_Print_Cb - * Type for print callbacks. - */ -typedef void (*Eina_Log_Print_Cb) (const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, const char *fnc, - int line, const char *fmt, void *data, - va_list args); - -/* - * Customization - */ -EAPI void -eina_log_print_cb_set(Eina_Log_Print_Cb cb, - void *data) EINA_ARG_NONNULL(1); - -EAPI void eina_log_level_set(int level); -EAPI int eina_log_level_get(void) EINA_WARN_UNUSED_RESULT; - -static inline Eina_Bool eina_log_level_check(int level); - -EAPI Eina_Bool eina_log_main_thread_check(void) -EINA_CONST EINA_WARN_UNUSED_RESULT; - -EAPI void eina_log_color_disable_set(Eina_Bool disabled); -EAPI Eina_Bool eina_log_color_disable_get(void) EINA_WARN_UNUSED_RESULT; -EAPI void eina_log_file_disable_set(Eina_Bool disabled); -EAPI Eina_Bool eina_log_file_disable_get(void) EINA_WARN_UNUSED_RESULT; -EAPI void eina_log_function_disable_set(Eina_Bool disabled); -EAPI Eina_Bool eina_log_function_disable_get(void) EINA_WARN_UNUSED_RESULT; -EAPI void eina_log_abort_on_critical_set(Eina_Bool abort_on_critical); -EAPI Eina_Bool -eina_log_abort_on_critical_get(void) EINA_WARN_UNUSED_RESULT; -EAPI void eina_log_abort_on_critical_level_set(int critical_level); -EAPI int -eina_log_abort_on_critical_level_get(void) EINA_WARN_UNUSED_RESULT; - -EAPI void -eina_log_domain_level_set(const char *domain_name, - int level) EINA_ARG_NONNULL(1); -EAPI int eina_log_domain_level_get(const char *domain_name) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); -EAPI int -eina_log_domain_registered_level_get(int domain) EINA_WARN_UNUSED_RESULT; -static inline Eina_Bool eina_log_domain_level_check(int domain, int level); - - -/* - * Logging domains - */ -EAPI int -eina_log_domain_register(const char *name, - const char *color) EINA_ARG_NONNULL(1); -EAPI void eina_log_domain_unregister(int domain); - -/* - * Logging functions. - */ -EAPI void -eina_log_print(int domain, - Eina_Log_Level level, - const char *file, - const char *function, - int line, - const char *fmt, - ...) EINA_ARG_NONNULL(3, 4, 6) EINA_PRINTF(6, - 7) -EINA_NOINSTRUMENT; -EAPI void eina_log_vprint(int domain, Eina_Log_Level level, - const char *file, const char *fnc, int line, - const char *fmt, - va_list args) EINA_ARG_NONNULL(3, 4, - 6) - EINA_NOINSTRUMENT; - - -/* - * Logging methods (change how logging is done). - */ -EAPI void -eina_log_print_cb_stdout(const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, - int line, - const char *fmt, void *data, va_list args); -EAPI void -eina_log_print_cb_stderr(const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, - int line, - const char *fmt, void *data, va_list args); -EAPI void -eina_log_print_cb_file(const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, - int line, - const char *fmt, void *data, va_list args); - -#include "eina_inline_log.x" - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_LOG_H_ */ diff --git a/tests/suite/ecore/src/include/eina_magic.h b/tests/suite/ecore/src/include/eina_magic.h deleted file mode 100644 index 87f4ce3e76..0000000000 --- a/tests/suite/ecore/src/include/eina_magic.h +++ /dev/null @@ -1,156 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_MAGIC_H_ -#define EINA_MAGIC_H_ - - -#include "eina_config.h" -#include "eina_types.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Magic_Group Magic - * - * @{ - */ - -typedef unsigned int Eina_Magic; - -/** - * @typedef Eina_Magic - * An abstract type for a magic number. - */ -EAPI const char *eina_magic_string_get(Eina_Magic magic) -EINA_PURE EINA_WARN_UNUSED_RESULT; -EAPI Eina_Bool eina_magic_string_set(Eina_Magic magic, - const char *magic_name) -EINA_ARG_NONNULL(2); -EAPI Eina_Bool eina_magic_string_static_set(Eina_Magic magic, - const char *magic_name) -EINA_ARG_NONNULL(2); - -/** - * @def EINA_MAGIC_NONE - * Random value for specifying that a structure using the magic - * feature has already been freed. It is used by eina_magic_fail(). - * - * If the magic feature of Eina is disabled, #EINA_MAGIC_NONE is just - * @c 0. - */ -#define EINA_MAGIC_NONE 0x1234fedc - -#ifdef EINA_MAGIC_DEBUG - -/** - * @def EINA_MAGIC - * Declaration of a variable of type #Eina_Magic. To put in a structure - * when one wants to use the magic feature of Eina with the functions - * of that structure, like that: - * - * @code - * struct Foo - * { - * int i; - * - * EINA_MAGIC - * }; - * @endcode - * - * If the magic feature of Eina is disabled, #EINA_MAGIC does nothing. - */ -#define EINA_MAGIC Eina_Magic __magic; - -/** - * @def EINA_MAGIC_SET(d, m) - * Set the magic number of @p d to @p m. @p d must be a valid pointer - * to a structure holding an Eina magic number declaration. Use - * #EINA_MAGIC to add such declaration. - * - * If the magic feature of Eina is disabled, #EINA_MAGIC_CHECK is just - * the value @c 0. - */ -#define EINA_MAGIC_SET(d, m) (d)->__magic = (m) - -/** - * @def EINA_MAGIC_CHECK(d, m) - * Test if @p d is @c NULL or not, and if not @c NULL, if - * @p d->__eina_magic is equal to @p m. @p d must be a structure that - * holds an Eina magic number declaration. Use #EINA_MAGIC to add such - * declaration. - * - * If the magic feature of Eina is disabled, #EINA_MAGIC_CHECK is just - * the value @c 1. - */ -#define EINA_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m))) - -/** - * @def EINA_MAGIC_FAIL(d, m) - * Call eina_magic_fail() with the parameters @p d, @p d->__magic, @p - * m, __FILE__, __FUNCTION__ and __LINE__. @p d must be a structure that - * holds an Eina magic number declaration. Use #EINA_MAGIC to add such - * declaration. - * - * If the magic feature of Eina is disabled, #EINA_MAGIC_FAIL does - * nothing. - */ -#define EINA_MAGIC_FAIL(d, m) \ - eina_magic_fail((void *)(d), \ - (d) ? (d)->__magic : 0, \ - (m), \ - __FILE__, \ - __FUNCTION__, \ - __LINE__); - -EAPI void eina_magic_fail(void *d, Eina_Magic m, Eina_Magic req_m, - const char *file, const char *fnc, - int line) EINA_ARG_NONNULL(4, 5); - -#else - -/** - * @cond LOCAL - */ - -#define EINA_MAGIC -#define EINA_MAGIC_SET(d, m) ((void)0) -#define EINA_MAGIC_CHECK(d, m) (1) -#define EINA_MAGIC_FAIL(d, m) ((void)0) - -#define eina_magic_fail(d, m, req_m, file, fnx, line) ((void)0) - -/** - * @endcond - */ - -#endif - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_MAGIC_H_ */ diff --git a/tests/suite/ecore/src/include/eina_main.h b/tests/suite/ecore/src/include/eina_main.h deleted file mode 100644 index 784ad050be..0000000000 --- a/tests/suite/ecore/src/include/eina_main.h +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_MAIN_H_ -#define EINA_MAIN_H_ - -#include "eina_types.h" - -/** - * @addtogroup Eina_Core_Group Core - * - * @{ - */ - -/** - * @defgroup Eina_Main_Group Main - * - * @{ - */ - -/** - * @def EINA_VERSION_MAJOR - * @brief Major version of Eina - */ -#define EINA_VERSION_MAJOR 1 - -/** - * @def EINA_VERSION_MINOR - * @brief Minor version of Eina - */ -#define EINA_VERSION_MINOR 0 - -/** - * @typedef Eina_Version - * The version of Eina. - */ -typedef struct _Eina_Version { - int major; - /**< Major component of the version */ - int minor; - /**< Minor component of the version */ - int micro; - /**< Micro component of the version */ - int revision; - /**< Revision component of the version */ -} Eina_Version; - -EAPI extern Eina_Version *eina_version; - -EAPI int eina_init(void); -EAPI int eina_shutdown(void); -EAPI int eina_threads_init(void); -EAPI int eina_threads_shutdown(void); - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_MAIN_H_ */ diff --git a/tests/suite/ecore/src/include/eina_matrixsparse.h b/tests/suite/ecore/src/include/eina_matrixsparse.h deleted file mode 100644 index fc63ec22ed..0000000000 --- a/tests/suite/ecore/src/include/eina_matrixsparse.h +++ /dev/null @@ -1,150 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2009 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_MATRIXSPARSE_H_ -#define EINA_MATRIXSPARSE_H_ - -#include <stdlib.h> - -#include "eina_config.h" - -#include "eina_types.h" -#include "eina_iterator.h" -#include "eina_accessor.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_Matrixsparse_Group Sparse Matrix - * - * @{ - */ - -/** - * @typedef Eina_Matrixsparse - * Type for a generic sparse matrix. - */ -typedef struct _Eina_Matrixsparse Eina_Matrixsparse; - -/** - * @typedef Eina_Matrixsparse_Row - * Type for a generic sparse matrix row, opaque for users. - */ -typedef struct _Eina_Matrixsparse_Row Eina_Matrixsparse_Row; - -/** - * @typedef Eina_Matrixsparse_Cell - * Type for a generic sparse matrix cell, opaque for users. - */ -typedef struct _Eina_Matrixsparse_Cell Eina_Matrixsparse_Cell; - -typedef struct _Eina_Matrixsparse_Item_Cell Eina_Matrixsparse_Item_Cell; -typedef struct _Eina_Matrixsparse_Item_Row Eina_Matrixsparse_Item_Row; - - -/* constructors and destructors */ -EAPI Eina_Matrixsparse *eina_matrixsparse_new(unsigned long rows, - unsigned long cols, - void (*free_func) (void - *user_data, - void - *cell_data), - const void *user_data); -EAPI void eina_matrixsparse_free(Eina_Matrixsparse * m); - -/* size manipulation */ -EAPI void eina_matrixsparse_size_get(const Eina_Matrixsparse * m, - unsigned long *rows, - unsigned long *cols); -EAPI Eina_Bool eina_matrixsparse_size_set(Eina_Matrixsparse * m, - unsigned long rows, - unsigned long cols); - -/* data getting */ -EAPI Eina_Bool eina_matrixsparse_cell_idx_get(const Eina_Matrixsparse * m, - unsigned long row, - unsigned long col, - Eina_Matrixsparse_Cell ** - cell); -EAPI void *eina_matrixsparse_cell_data_get(const Eina_Matrixsparse_Cell * - cell); -EAPI void *eina_matrixsparse_data_idx_get(const Eina_Matrixsparse * m, - unsigned long row, - unsigned long col); -EAPI Eina_Bool eina_matrixsparse_cell_position_get(const - Eina_Matrixsparse_Cell * - cell, - unsigned long *row, - unsigned long *col); - -/* data setting */ -EAPI Eina_Bool eina_matrixsparse_cell_data_replace(Eina_Matrixsparse_Cell * - cell, const void *data, - void **p_old); -EAPI Eina_Bool eina_matrixsparse_cell_data_set(Eina_Matrixsparse_Cell * - cell, const void *data); -EAPI Eina_Bool eina_matrixsparse_data_idx_replace(Eina_Matrixsparse * m, - unsigned long row, - unsigned long col, - const void *data, - void **p_old); -EAPI Eina_Bool eina_matrixsparse_data_idx_set(Eina_Matrixsparse * m, - unsigned long row, - unsigned long col, - const void *data); - -/* data deleting */ -EAPI Eina_Bool eina_matrixsparse_row_idx_clear(Eina_Matrixsparse * m, - unsigned long row); -EAPI Eina_Bool eina_matrixsparse_column_idx_clear(Eina_Matrixsparse * m, - unsigned long col); -EAPI Eina_Bool eina_matrixsparse_cell_idx_clear(Eina_Matrixsparse * m, - unsigned long row, - unsigned long col); -EAPI Eina_Bool eina_matrixsparse_cell_clear(Eina_Matrixsparse_Cell * cell); - -/* iterators */ -EAPI Eina_Iterator *eina_matrixsparse_iterator_new(const Eina_Matrixsparse - * m); -EAPI Eina_Iterator *eina_matrixsparse_iterator_complete_new(const - Eina_Matrixsparse - * m); - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_MATRIXSPARSE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_mempool.h b/tests/suite/ecore/src/include/eina_mempool.h deleted file mode 100644 index 1588cad396..0000000000 --- a/tests/suite/ecore/src/include/eina_mempool.h +++ /dev/null @@ -1,87 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_MEMPOOL_H_ -#define EINA_MEMPOOL_H_ - -#include "eina_types.h" -#include "eina_error.h" -#include "eina_module.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Memory_Pool_Group Memory Pool - * - * @{ - */ - -/** - * @typedef Eina_Mempool - * Mempool type. - */ -typedef struct _Eina_Mempool Eina_Mempool; - -/** - * @typedef Eina_Mempool_Backend - * Mempool backend type. - */ -typedef struct _Eina_Mempool_Backend Eina_Mempool_Backend; - -EAPI extern Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE; - -EAPI Eina_Mempool *eina_mempool_add(const char *module, - const char *context, - const char *options, ...) -EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); -EAPI void eina_mempool_del(Eina_Mempool * mp) EINA_ARG_NONNULL(1); - -static inline void *eina_mempool_realloc(Eina_Mempool * mp, void *element, - unsigned int size) -EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -static inline void *eina_mempool_malloc(Eina_Mempool * mp, - unsigned int size) -EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -static inline void eina_mempool_free(Eina_Mempool * mp, - void *element) EINA_ARG_NONNULL(1); - -EAPI void eina_mempool_gc(Eina_Mempool * mp) EINA_ARG_NONNULL(1); -EAPI void eina_mempool_statistics(Eina_Mempool * mp) EINA_ARG_NONNULL(1); - -EAPI Eina_Bool eina_mempool_register(Eina_Mempool_Backend * - be) EINA_ARG_NONNULL(1); -EAPI void eina_mempool_unregister(Eina_Mempool_Backend * - be) EINA_ARG_NONNULL(1); - -EAPI unsigned int eina_mempool_alignof(unsigned int size); - -#include "eina_inline_mempool.x" - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_MEMPOOL_H_ */ diff --git a/tests/suite/ecore/src/include/eina_module.h b/tests/suite/ecore/src/include/eina_module.h deleted file mode 100644 index 91918fbe46..0000000000 --- a/tests/suite/ecore/src/include/eina_module.h +++ /dev/null @@ -1,149 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_MODULE_H_ -#define EINA_MODULE_H_ - -#include "eina_types.h" -#include "eina_array.h" -#include "eina_error.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Module_Group Module - * - * Eina module provides some helpers over POSIX dlopen(). It is not - * meant to replace, abstract or make a "portable" version of the - * POSIX, but enhance its usage by defining some good practices. - * - * Modules are created with eina_module_new() and later loaded with - * eina_module_load(). Loads are reference counted and there must be - * the same number of eina_module_unload() in order to have it to call - * dlclose(). This makes simple to have different users for the same - * module. - * - * The loaded shared objects may have two visible functions that will - * be called and might provide initialization and shutdown - * proceedures. The symbols are @c __eina_module_init and - * @c __eina_module_shutdown and will be defined by the macros - * EINA_MODULE_INIT() and EINA_MODULE_SHUTDOWN(). - * - * There are some helpers to automatically create modules based on - * directory listing. See eina_module_arch_list_get(), - * eina_module_list_get() and eina_module_find(). - * - * @{ - */ - -/** - * @typedef Eina_Module - * Dynamic module loader handle. - */ -typedef struct _Eina_Module Eina_Module; - -typedef Eina_Bool(*Eina_Module_Cb) (Eina_Module * m, void *data); - -/** - * @typedef Eina_Module_Init - * If a function with such signature is exported by module as - * __eina_module_init, it will be called on the first load after - * dlopen() and if #EINA_FALSE is returned, load will fail, #EINA_TRUE - * means the module was successfully initialized. - * @see Eina_Module_Shutdown - */ -typedef Eina_Bool(*Eina_Module_Init) (void); - -/** - * @typedef Eina_Module_Shutdown - * If a function with such signature is exported by module as - * __eina_module_shutdown, it will be called before calling dlclose() - * @see Eina_Module_Init - */ -typedef void (*Eina_Module_Shutdown) (void); - -/** - * @def EINA_MODULE_INIT - * declares the given function as the module initializer (__eina_module_init). - * It must be of signature #Eina_Module_Init - */ -#define EINA_MODULE_INIT(f) EAPI Eina_Module_Init __eina_module_init = &f - -/** - * @def EINA_MODULE_SHUTDOWN - * declares the given function as the module shutdownializer - * (__eina_module_shutdown). It must be of signature - * #Eina_Module_Shutdown - */ -#define EINA_MODULE_SHUTDOWN(f) EAPI Eina_Module_Shutdown __eina_module_shutdown = &f - -/** - * @var EINA_ERROR_WRONG_MODULE - * Error identifier corresponding to a wrong module. - */ -extern EAPI Eina_Error EINA_ERROR_WRONG_MODULE; - -/** - * @var EINA_ERROR_MODULE_INIT_FAILED - * Error identifier corresponding to a failure during the initialisation of a module. - */ -extern EAPI Eina_Error EINA_ERROR_MODULE_INIT_FAILED; - -EAPI Eina_Module *eina_module_new(const char *file) -EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_module_free(Eina_Module * m) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_module_load(Eina_Module * module) EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_module_unload(Eina_Module * m) EINA_ARG_NONNULL(1); -EAPI void *eina_module_symbol_get(const Eina_Module * module, - const char *symbol) -EINA_PURE EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; -EAPI const char *eina_module_file_get(const Eina_Module * m) -EINA_PURE EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); - -EAPI char *eina_module_symbol_path_get(const void *symbol, - const char *sub_dir); -EAPI char *eina_module_environment_path_get(const char *env, - const char *sub_dir); - -EAPI Eina_Array *eina_module_arch_list_get(Eina_Array * array, - const char *path, - const char *arch); -EAPI Eina_Array *eina_module_list_get(Eina_Array * array, const char *path, - Eina_Bool recursive, - Eina_Module_Cb cb, void *data) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI void eina_module_list_load(Eina_Array * list) EINA_ARG_NONNULL(1); -EAPI void eina_module_list_unload(Eina_Array * list) EINA_ARG_NONNULL(1); -EAPI void eina_module_list_free(Eina_Array * list) EINA_ARG_NONNULL(1); -EAPI Eina_Module *eina_module_find(const Eina_Array * array, - const char *module) EINA_ARG_NONNULL(1, - 2); - -/** - * @} - */ - -/** - * @} - */ - -#endif /*EINA_MODULE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_quadtree.h b/tests/suite/ecore/src/include/eina_quadtree.h deleted file mode 100644 index cbd4c220c8..0000000000 --- a/tests/suite/ecore/src/include/eina_quadtree.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_QUADTREE_H_ -#define EINA_QUADTREE_H_ - -#include "eina_config.h" - -#include "eina_inlist.h" - -typedef struct _Eina_QuadTree Eina_QuadTree; -typedef struct _Eina_QuadTree_Item Eina_QuadTree_Item; - -typedef enum { - EINA_QUAD_LEFT, - EINA_QUAD_RIGHT, - EINA_QUAD_BOTH -} Eina_Quad_Direction; - -typedef Eina_Quad_Direction(*Eina_Quad_Callback) (const void *object, - size_t middle); - -EAPI Eina_QuadTree *eina_quadtree_new(size_t w, size_t h, - Eina_Quad_Callback vertical, - Eina_Quad_Callback horizontal); -EAPI void eina_quadtree_free(Eina_QuadTree * q); -EAPI void eina_quadtree_resize(Eina_QuadTree * q, size_t w, size_t h); - -EAPI void eina_quadtree_cycle(Eina_QuadTree * q); -EAPI void eina_quadtree_increase(Eina_QuadTree_Item * object); - -EAPI Eina_QuadTree_Item *eina_quadtree_add(Eina_QuadTree * q, - const void *object); -EAPI Eina_Bool eina_quadtree_del(Eina_QuadTree_Item * object); -EAPI Eina_Bool eina_quadtree_change(Eina_QuadTree_Item * object); -EAPI Eina_Bool eina_quadtree_hide(Eina_QuadTree_Item * object); -EAPI Eina_Bool eina_quadtree_show(Eina_QuadTree_Item * object); - -EAPI Eina_Inlist *eina_quadtree_collide(Eina_QuadTree * q, int x, int y, - int w, int h); -EAPI void *eina_quadtree_object(Eina_Inlist * list); - -#endif diff --git a/tests/suite/ecore/src/include/eina_rbtree.h b/tests/suite/ecore/src/include/eina_rbtree.h deleted file mode 100644 index 6bb6f1a53e..0000000000 --- a/tests/suite/ecore/src/include/eina_rbtree.h +++ /dev/null @@ -1,179 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_RBTREE_H__ -#define EINA_RBTREE_H__ - -#include <stdlib.h> - -#include "eina_types.h" -#include "eina_error.h" -#include "eina_iterator.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_Rbtree_Group Red-Black tree - * - * @{ - */ - -/** - * @typedef Eina_Rbtree_Color - * node color. - */ -typedef enum { - EINA_RBTREE_RED, - EINA_RBTREE_BLACK -} Eina_Rbtree_Color; - -/** - * @typedef Eina_Rbtree_Direction - * walk direction. - */ -typedef enum { - EINA_RBTREE_LEFT = 0, - EINA_RBTREE_RIGHT = 1 -} Eina_Rbtree_Direction; - -/** - * @typedef Eina_Rbtree - * Type for a Red-Black tree node. It should be inlined into user's type. - */ -typedef struct _Eina_Rbtree Eina_Rbtree; -struct _Eina_Rbtree { - Eina_Rbtree *son[2]; - - Eina_Rbtree_Color color:1; -}; - -/** - * @def EINA_RBTREE - * recommended way to declare the inlined Eina_Rbtree in your type. - * - * @code - * struct my_type { - * EINA_RBTREE; - * int my_value; - * char *my_name; - * }; - * @endcode - * - * @see EINA_RBTREE_GET() - */ -#define EINA_RBTREE Eina_Rbtree __rbtree - -/** - * @def EINA_RBTREE_GET - * access the inlined node if it was created with #EINA_RBTREE. - */ -#define EINA_RBTREE_GET(Rbtree) & ((Rbtree)->__rbtree) - -/** - * @typedef Eina_Rbtree_Cmp_Node_Cb - * Function used compare two nodes and see which direction to navigate. - */ -typedef Eina_Rbtree_Direction(*Eina_Rbtree_Cmp_Node_Cb) (const Eina_Rbtree - * left, - const Eina_Rbtree - * right, - void *data); - -/** - * @def EINA_RBTREE_CMP_NODE_CB - * Cast using #Eina_Rbtree_Cmp_Node_Cb - */ -#define EINA_RBTREE_CMP_NODE_CB(Function) ((Eina_Rbtree_Cmp_Node_Cb)Function) - -/** - * @typedef Eina_Rbtree_Cmp_Key_Cb - * Function used compare node with a given key of specified length. - */ -typedef int (*Eina_Rbtree_Cmp_Key_Cb) (const Eina_Rbtree * node, - const void *key, int length, - void *data); -/** - * @def EINA_RBTREE_CMP_KEY_CB - * Cast using #Eina_Rbtree_Cmp_Key_Cb - */ -#define EINA_RBTREE_CMP_KEY_CB(Function) ((Eina_Rbtree_Cmp_Key_Cb)Function) - -/** - * @typedef Eina_Rbtree_Free_Cb - * Function used free a node. - */ -typedef void (*Eina_Rbtree_Free_Cb) (Eina_Rbtree * node, void *data); -/** - * @def EINA_RBTREE_FREE_CB - * Cast using #Eina_Rbtree_Free_Cb - */ -#define EINA_RBTREE_FREE_CB(Function) ((Eina_Rbtree_Free_Cb)Function) - -EAPI Eina_Rbtree *eina_rbtree_inline_insert(Eina_Rbtree * root, - Eina_Rbtree * node, - Eina_Rbtree_Cmp_Node_Cb cmp, - const void *data) -EINA_ARG_NONNULL(2, 3) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Rbtree *eina_rbtree_inline_remove(Eina_Rbtree * root, - Eina_Rbtree * node, - Eina_Rbtree_Cmp_Node_Cb cmp, - const void *data) -EINA_ARG_NONNULL(2, 3) EINA_WARN_UNUSED_RESULT; -EAPI void eina_rbtree_delete(Eina_Rbtree * root, Eina_Rbtree_Free_Cb func, - void *data) EINA_ARG_NONNULL(2); - -static inline Eina_Rbtree *eina_rbtree_inline_lookup(const Eina_Rbtree * - root, const void *key, - int length, - Eina_Rbtree_Cmp_Key_Cb - cmp, const void *data) -EINA_PURE EINA_ARG_NONNULL(2, 4) EINA_WARN_UNUSED_RESULT; - -EAPI Eina_Iterator *eina_rbtree_iterator_prefix(const Eina_Rbtree * root) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI Eina_Iterator *eina_rbtree_iterator_infix(const Eina_Rbtree * root) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI Eina_Iterator *eina_rbtree_iterator_postfix(const Eina_Rbtree * root) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; - -#include "eina_inline_rbtree.x" - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_rectangle.h b/tests/suite/ecore/src/include/eina_rectangle.h deleted file mode 100644 index 0910891505..0000000000 --- a/tests/suite/ecore/src/include/eina_rectangle.h +++ /dev/null @@ -1,158 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_RECTANGLE_H_ -#define EINA_RECTANGLE_H_ - -#include "eina_types.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Rectangle_Group Rectangle - * - * @{ - */ - -/** - * @typedef Eina_Rectangle - * Simple rectangle structure. - */ -typedef struct _Eina_Rectangle { - int x; - /**< top-left x co-ordinate of rectangle */ - int y; - /**< top-left y co-ordinate of rectangle */ - int w; - /**< width of rectangle */ - int h; - /**< height of rectangle */ -} Eina_Rectangle; - -/** - * @typedef Eina_Rectangle_Pool - * Type for an opaque pool of rectangle. - */ -typedef struct _Eina_Rectangle_Pool Eina_Rectangle_Pool; - -static inline int eina_spans_intersect(int c1, int l1, int c2, - int l2) EINA_WARN_UNUSED_RESULT; -static inline Eina_Bool eina_rectangle_is_empty(const Eina_Rectangle * - r) EINA_ARG_NONNULL(1) - EINA_WARN_UNUSED_RESULT; -static inline void eina_rectangle_coords_from(Eina_Rectangle * r, int x, - int y, int w, - int h) EINA_ARG_NONNULL(1); -static inline Eina_Bool eina_rectangles_intersect(const Eina_Rectangle * - r1, - const Eina_Rectangle * - r2) EINA_ARG_NONNULL(1, - 2) - EINA_WARN_UNUSED_RESULT; -static inline Eina_Bool eina_rectangle_xcoord_inside(const Eina_Rectangle * - r, - int x) -EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -static inline Eina_Bool eina_rectangle_ycoord_inside(const Eina_Rectangle * - r, - int y) -EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -static inline Eina_Bool eina_rectangle_coords_inside(const Eina_Rectangle * - r, int x, - int y) -EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -static inline void eina_rectangle_union(Eina_Rectangle * dst, - const Eina_Rectangle * - src) EINA_ARG_NONNULL(1, 2); -static inline Eina_Bool eina_rectangle_intersection(Eina_Rectangle * dst, - const Eina_Rectangle * - src) -EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; -static inline void eina_rectangle_rescale_in(const Eina_Rectangle * out, - const Eina_Rectangle * in, - Eina_Rectangle * - res) EINA_ARG_NONNULL(1, 2, - 3); -static inline void eina_rectangle_rescale_out(const Eina_Rectangle * out, - const Eina_Rectangle * in, - Eina_Rectangle * - res) EINA_ARG_NONNULL(1, 2, - 3); - -EAPI Eina_Rectangle_Pool *eina_rectangle_pool_new(int w, int h) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI Eina_Rectangle_Pool *eina_rectangle_pool_get(Eina_Rectangle * rect) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); -EAPI Eina_Bool eina_rectangle_pool_geometry_get(Eina_Rectangle_Pool * pool, - int *w, int *h) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; -EAPI void *eina_rectangle_pool_data_get(Eina_Rectangle_Pool * pool) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); -EAPI void eina_rectangle_pool_data_set(Eina_Rectangle_Pool * pool, - const void *data) -EINA_ARG_NONNULL(1); -EAPI void eina_rectangle_pool_free(Eina_Rectangle_Pool * - pool) EINA_ARG_NONNULL(1); -EAPI int eina_rectangle_pool_count(Eina_Rectangle_Pool * - pool) EINA_ARG_NONNULL(1) - EINA_WARN_UNUSED_RESULT; -EAPI Eina_Rectangle *eina_rectangle_pool_request(Eina_Rectangle_Pool * - pool, int w, int h) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); -EAPI void eina_rectangle_pool_release(Eina_Rectangle * - rect) EINA_ARG_NONNULL(1); - -/** - * @def EINA_RECTANGLE_SET - * @brief Macro to set the values of a #Eina_Rectangle. - * - * @param Rectangle The rectangle to set the values. - * @param X The X coordinate of the top left corner of the rectangle. - * @param Y The Y coordinate of the top left corner of the rectangle. - * @param W The width of the rectangle. - * @param H The height of the rectangle. - * - * This macro set the values of @p Rectangle. (@p X, @p Y) is the - * coordinates of the top left corner of @p Rectangle, @p W is its - * width and @p H is its height. - */ -#define EINA_RECTANGLE_SET(Rectangle, X, Y, W, H) \ - (Rectangle)->x = X; \ - (Rectangle)->y = Y; \ - (Rectangle)->w = W; \ - (Rectangle)->h = H; - -EAPI Eina_Rectangle *eina_rectangle_new(int x, int y, int w, int h) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI void eina_rectangle_free(Eina_Rectangle * rect) EINA_ARG_NONNULL(1); - -#include "eina_inline_rectangle.x" - -/** - * @} - */ - -/** - * @} - */ - -#endif /*_EINA_RECTANGLE_H_*/ diff --git a/tests/suite/ecore/src/include/eina_safety_checks.h b/tests/suite/ecore/src/include/eina_safety_checks.h deleted file mode 100644 index 9a67572d5b..0000000000 --- a/tests/suite/ecore/src/include/eina_safety_checks.h +++ /dev/null @@ -1,234 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_SAFETY_CHECKS_H_ -#define EINA_SAFETY_CHECKS_H_ - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_Safety_Checks_Group Safety Checks - * - * @warning @c eina_safety_checks.h should only be included by source - * files, after all other includes and before the source file - * specific includes. By source file specific includes we - * mean those that define the functions that are being - * checked. The reason for such complexity is the trick to - * avoid compiler optimizations. If compilers are told that - * some given function will never receive @c NULL - * (EINA_ARG_NONNULL(), then compiler will emit a warning if - * it detects so (good!) but will remove any checks for that - * condition as it believes it will never happen, removing - * all safety checks! By including @c eina_safety_checks.h it - * will redefine EINA_ARG_NONNULL() to void and compiler - * warning will not be emitted, but checks will be there. The - * files already processed with the old macro - * EINA_ARG_NONNULL() will still work and emit the warnings. - * - * - * @code - * - * // all these files will emit warning from EINA_ARG_NONNULL() - * #include <Evas.h> // third party headers - * #include <Ecore.h> - * #include <eina_error.h> // eina own header - * - * #include <eina_safety_checks.h> - * // all these files below will NOT emit warning from EINA_ARG_NONNULL(), - * // but this is required to have the functions defined there to be checked - * // for NULL pointers - * #include "my_functions1.h" - * #include "my_functions2.h" - * - * @endcode - * - * @{ - */ - - -#include "eina_config.h" -#include "eina_error.h" - -/** - * @var EINA_ERROR_SAFETY_FAILED - * Error identifier corresponding to safety check failure. - */ -EAPI extern Eina_Error EINA_ERROR_SAFETY_FAILED; - -#ifdef EINA_SAFETY_CHECKS - -#include "eina_log.h" - -#define EINA_SAFETY_ON_NULL_RETURN(exp) \ - do \ - { \ - if (EINA_UNLIKELY((exp) == NULL)) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " == NULL"); \ - return; \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_NULL_RETURN_VAL(exp, val) \ - do \ - { \ - if (EINA_UNLIKELY((exp) == NULL)) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " == NULL"); \ - return (val); \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_NULL_GOTO(exp, label) \ - do \ - { \ - if (EINA_UNLIKELY((exp) == NULL)) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " == NULL"); \ - goto label; \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_TRUE_RETURN(exp) \ - do \ - { \ - if (EINA_UNLIKELY(exp)) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " is true"); \ - return; \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_TRUE_RETURN_VAL(exp, val) \ - do \ - { \ - if (EINA_UNLIKELY(exp)) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " is true"); \ - return val; \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_TRUE_GOTO(exp, label) \ - do \ - { \ - if (EINA_UNLIKELY(exp)) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " is true"); \ - goto label; \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_FALSE_RETURN(exp) \ - do \ - { \ - if (EINA_UNLIKELY(!(exp))) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " is false"); \ - return; \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_FALSE_RETURN_VAL(exp, val) \ - do \ - { \ - if (EINA_UNLIKELY(!(exp))) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " is false"); \ - return val; \ - } \ - } \ - while (0) - -#define EINA_SAFETY_ON_FALSE_GOTO(exp, label) \ - do \ - { \ - if (EINA_UNLIKELY(!(exp))) \ - { \ - eina_error_set(EINA_ERROR_SAFETY_FAILED); \ - EINA_LOG_ERR("%s", "safety check failed: " # exp " is false"); \ - goto label; \ - } \ - } \ - while (0) - -#ifdef EINA_ARG_NONNULL -/* make EINA_ARG_NONNULL void so GCC does not optimize safety checks */ -#undef EINA_ARG_NONNULL -#define EINA_ARG_NONNULL(idx, ...) -#endif - - -#else /* no safety checks */ - -#define EINA_SAFETY_ON_NULL_RETURN(exp) \ - do { (void)(!(exp)); } while (0) - -#define EINA_SAFETY_ON_NULL_RETURN_VAL(exp, val) \ - do { if (0 && !(exp)) { (void)val; } } while (0) - -#define EINA_SAFETY_ON_NULL_GOTO(exp, label) \ - do { if (0 && (exp) == NULL) { goto label; } } while (0) - -#define EINA_SAFETY_ON_TRUE_RETURN(exp) \ - do { (void)(exp); } while (0) - -#define EINA_SAFETY_ON_TRUE_RETURN_VAL(exp, val) \ - do { if (0 && (exp)) { (void)val; } } while (0) - -#define EINA_SAFETY_ON_TRUE_GOTO(exp, label) \ - do { if (0 && (exp)) { goto label; } } while (0) - -#define EINA_SAFETY_ON_FALSE_RETURN(exp) \ - do { (void)(!(exp)); } while (0) - -#define EINA_SAFETY_ON_FALSE_RETURN_VAL(exp, val) \ - do { if (0 && !(exp)) { (void)val; } } while (0) - -#define EINA_SAFETY_ON_FALSE_GOTO(exp, label) \ - do { if (0 && !(exp)) { goto label; } } while (0) - -#endif /* safety checks macros */ -#endif /* EINA_SAFETY_CHECKS_H_ */ - -/** - * @} - */ - -/** - * @} - */ diff --git a/tests/suite/ecore/src/include/eina_sched.h b/tests/suite/ecore/src/include/eina_sched.h deleted file mode 100644 index 017aa2df51..0000000000 --- a/tests/suite/ecore/src/include/eina_sched.h +++ /dev/null @@ -1,26 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2010 ProFUSION embedded systems - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_SCHED_H_ -#define EINA_SCHED_H_ - -#include "eina_types.h" - -EAPI void eina_sched_prio_drop(void); - -#endif /* EINA_SCHED_H_ */ diff --git a/tests/suite/ecore/src/include/eina_str.h b/tests/suite/ecore/src/include/eina_str.h deleted file mode 100644 index 736fa6a7a4..0000000000 --- a/tests/suite/ecore/src/include/eina_str.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _EINA_STR_H -#define _EINA_STR_H - -#include <stddef.h> -#include <string.h> - -#include "eina_types.h" - -/** - * @addtogroup Eina_Tools_Group Tools - * - * @{ - */ - -/** - * @defgroup Eina_String_Group String - * - * @{ - */ - -/* strlcpy implementation for libc's lacking it */ -EAPI size_t eina_strlcpy(char *dst, const char *src, - size_t siz) EINA_ARG_NONNULL(1, 2); -EAPI size_t eina_strlcat(char *dst, const char *src, - size_t siz) EINA_ARG_NONNULL(1, 2); - -EAPI Eina_Bool eina_str_has_prefix(const char *str, const char *prefix) -EINA_PURE EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Bool eina_str_has_suffix(const char *str, const char *suffix) -EINA_PURE EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; -EAPI Eina_Bool eina_str_has_extension(const char *str, const char *ext) -EINA_PURE EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; - -EAPI char **eina_str_split(const char *string, const char *delimiter, - int max_tokens) EINA_ARG_NONNULL(1, 2) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; -EAPI char **eina_str_split_full(const char *string, const char *delimiter, - int max_tokens, - unsigned int *elements) EINA_ARG_NONNULL(1, - 2, - 4) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; - -EAPI size_t eina_str_join_len(char *dst, size_t size, char sep, - const char *a, size_t a_len, const char *b, - size_t b_len) EINA_ARG_NONNULL(1, 4, 6); - -EAPI char *eina_str_convert(const char *enc_from, const char *enc_to, - const char *text) -EINA_WARN_UNUSED_RESULT EINA_MALLOC EINA_ARG_NONNULL(1, 2, 3); - -EAPI char *eina_str_escape(const char *str) -EINA_WARN_UNUSED_RESULT EINA_MALLOC EINA_ARG_NONNULL(1); - -EAPI void eina_str_tolower(char **str); -EAPI void eina_str_toupper(char **str); - -static inline size_t eina_str_join(char *dst, size_t size, char sep, - const char *a, - const char *b) EINA_ARG_NONNULL(1, 4, - 5); - -/** - * @def eina_str_join_static(dst, sep, a, b) - * @brief Join two static strings and store the result in a static buffer. - * - * @param dst The buffer to store the result. - * @param sep The separator character to use. - * @param a First string to use, before @p sep. - * @param b Second string to use, after @p sep. - * @return The number of characters printed. - * - * This function is similar to eina_str_join_len(), but will assume - * string sizes are know using sizeof(X). - * - * @see eina_str_join() - * @see eina_str_join_static() - */ -#define eina_str_join_static(dst, sep, a, b) eina_str_join_len(dst, sizeof(dst), sep, a, (sizeof(a) > 0) ? sizeof(a) - 1 : 0, b, (sizeof(b) > 0) ? sizeof(b) - 1 : 0) - -static inline size_t eina_strlen_bounded(const char *str, size_t maxlen) -EINA_PURE EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); - -#include "eina_inline_str.x" - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_STR_H */ diff --git a/tests/suite/ecore/src/include/eina_strbuf.h b/tests/suite/ecore/src/include/eina_strbuf.h deleted file mode 100644 index 432fe5f179..0000000000 --- a/tests/suite/ecore/src/include/eina_strbuf.h +++ /dev/null @@ -1,521 +0,0 @@ -#ifndef EINA_STRBUF_H -#define EINA_STRBUF_H - -#include <stddef.h> -#include <stdarg.h> - -#include "eina_types.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @defgroup Eina_String_Buffer_Group String Buffer - * - * @{ - */ - -/** - * @typedef Eina_Strbuf - * Type for a string buffer. - */ -typedef struct _Eina_Strbuf Eina_Strbuf; - -/** - * @brief Create a new string buffer. - * - * @return Newly allocated string buffer instance. - * - * This function creates a new string buffer. On error, @c NULL is - * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To - * free the resources, use eina_strbuf_free(). - * - * @see eina_strbuf_free() - * @see eina_strbuf_append() - * @see eina_strbuf_string_get() - */ -EAPI Eina_Strbuf *eina_strbuf_new(void) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; - -/** - * @brief Free a string buffer. - * - * @param buf The string buffer to free. - * - * This function frees the memory of @p buf. @p buf must have been - * created by eina_strbuf_new(). - */ -EAPI void eina_strbuf_free(Eina_Strbuf * buf) EINA_ARG_NONNULL(1); - -/** - * @brief Reset a string buffer. - * - * @param buf The string buffer to reset. - * - * This function reset @p buf: the buffer len is set to 0, and the - * string is set to '\\0'. No memory is free'd. - */ -EAPI void eina_strbuf_reset(Eina_Strbuf * buf) EINA_ARG_NONNULL(1); - -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. It computes the length of - * @p str, so is slightly slower than eina_strbuf_append_length(). If - * the length is known beforehand, consider using that variant. If - * @p buf can't append it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - * - * @see eina_strbuf_append() - * @see eina_strbuf_append_length() - */ -EAPI Eina_Bool eina_strbuf_append(Eina_Strbuf * buf, - const char *str) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Append an escaped string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends the escaped string @p str to @p buf. If @p - * str can not be appended, #EINA_FALSE is returned, otherwise, - * #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_strbuf_append_escaped(Eina_Strbuf * buf, - const char *str) -EINA_ARG_NONNULL(1, 2); - -/** - * @brief Append a string to a buffer, reallocating as necessary, - * limited by the given length. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param maxlen The maximum number of characters to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends at most @p maxlen characters of @p str to - * @p buf. It can't appends more than the length of @p str. It - * computes the length of @p str, so is slightly slower than - * eina_strbuf_append_length(). If the length is known beforehand, - * consider using that variant (@p maxlen should then be checked so - * that it is greater than the size of @p str). If @p str can not be - * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is - * returned. - * - * @see eina_strbuf_append() - * @see eina_strbuf_append_length() - */ -EAPI Eina_Bool eina_strbuf_append_n(Eina_Strbuf * buf, const char *str, - size_t maxlen) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Append a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param length The exact length to use. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_strbuf_append() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_strbuf_append() - * @see eina_strbuf_append_n() - */ -EAPI Eina_Bool eina_strbuf_append_length(Eina_Strbuf * buf, - const char *str, - size_t length) EINA_ARG_NONNULL(1, - 2); - -/** - * @brief Append a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to append to. - * @param c The char to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf. If it can not insert it, - * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_strbuf_append_char(Eina_Strbuf * buf, - char c) EINA_ARG_NONNULL(1); - -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param fmt The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * @see eina_strbuf_append() - */ -EAPI Eina_Bool eina_strbuf_append_printf(Eina_Strbuf * buf, - const char *fmt, - ...) EINA_ARG_NONNULL(1, - 2) -EINA_PRINTF(2, 3); - -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param fmt The string to append. - * @param args The variable arguments. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * @see eina_strbuf_append() - */ -EAPI Eina_Bool eina_strbuf_append_vprintf(Eina_Strbuf * buf, - const char *fmt, - va_list args) EINA_ARG_NONNULL(1, - 2); - -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param str The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf at position @p pos. It - * computes the length of @p str, so is slightly slower than - * eina_strbuf_insert_length(). If the length is known beforehand, - * consider using that variant. If @p buf can't insert it, #EINA_FALSE - * is returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_strbuf_insert(Eina_Strbuf * buf, const char *str, - size_t pos) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Insert an escaped string to a buffer, reallocating as - * necessary. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts the escaped string @p str to @p buf at - * position @p pos. If @p buf can't insert @p str, #EINA_FALSE is - * returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_strbuf_insert_escaped(Eina_Strbuf * buf, - const char *str, - size_t pos) EINA_ARG_NONNULL(1, - 2); - -/** - * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param maxlen The maximum number of chars to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str ot @p buf at position @p pos, with at - * most @p maxlen bytes. The number of inserted characters can not be - * greater than the length of @p str. It computes the length of - * @p str, so is slightly slower than eina_strbuf_insert_length(). If the - * length is known beforehand, consider using that variant (@p maxlen - * should then be checked so that it is greater than the size of - * @p str). If @p str can not be inserted, #EINA_FALSE is returned, - * otherwise, #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_strbuf_insert_n(Eina_Strbuf * buf, const char *str, - size_t maxlen, - size_t pos) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Insert a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param length The exact length to use. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_strbuf_insert() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_strbuf_insert() - * @see eina_strbuf_insert_n() - */ -EAPI Eina_Bool eina_strbuf_insert_length(Eina_Strbuf * buf, - const char *str, size_t length, - size_t pos) EINA_ARG_NONNULL(1, - 2); - -/** - * @brief Insert a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to insert to. - * @param c The char to insert. - * @param pos The position to insert the char. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf at position @p pos. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -EAPI Eina_Bool eina_strbuf_insert_char(Eina_Strbuf * buf, char c, - size_t pos) EINA_ARG_NONNULL(1); - -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param fmt The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -EAPI Eina_Bool eina_strbuf_insert_printf(Eina_Strbuf * buf, - const char *fmt, size_t pos, - ...) EINA_ARG_NONNULL(1, - 2) -EINA_PRINTF(2, 4); - -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param fmt The string to insert. - * @param pos The position to insert the string. - * @param args The variable arguments. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -EAPI Eina_Bool eina_strbuf_insert_vprintf(Eina_Strbuf * buf, - const char *fmt, size_t pos, - va_list args) EINA_ARG_NONNULL(1, - 2); - -/** - * @def eina_strbuf_prepend(buf, str) - * @brief Prepend the given string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_insert() at position 0.If @p buf - * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -#define eina_strbuf_prepend(buf, str) eina_strbuf_insert(buf, str, 0) - -/** - * @def eina_strbuf_prepend_escaped(buf, str) - * @brief Prepend the given escaped string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_insert_escaped() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_strbuf_prepend_escaped(buf, str) eina_strbuf_insert_escaped(buf, str, 0) - -/** - * @def eina_strbuf_prepend_n(buf, str) - * @brief Prepend the given escaped string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @param maxlen The maximum number of chars to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_insert_n() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_strbuf_prepend_n(buf, str, maxlen) eina_strbuf_insert_n(buf, str, maxlen, 0) - -/** - * @def eina_strbuf_prepend_length(buf, str) - * @brief Prepend the given escaped string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @param length The exact length to use. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_insert_length() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_strbuf_prepend_length(buf, str, length) eina_strbuf_insert_length( buf, str, length, 0) - -/** - * @def eina_strbuf_prepend_char(buf, str) - * @brief Prepend the given character to the given buffer - * - * @param buf The string buffer to prepend to. - * @param c The character to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_insert_char() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_strbuf_prepend_char(buf, c) eina_strbuf_insert_char(buf, c, 0) - -/** - * @def eina_strbuf_prepend_printf(buf, fmt, ...) - * @brief Prepend the given string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param fmt The string to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_insert_printf() at position 0.If @p buf - * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -#define eina_strbuf_prepend_printf(buf, fmt, ...) eina_strbuf_insert_printf(buf, fmt, 0, ## __VA_ARGS__) - -/** - * @def eina_strbuf_prepend_vprintf(buf, fmt, args) - * @brief Prepend the given string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param fmt The string to prepend. - * @param args The variable arguments. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_insert_vprintf() at position 0.If @p buf - * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -#define eina_strbuf_prepend_vprintf(buf, fmt, args) eina_strbuf_insert_vprintf(buf, fmt, 0, args) - -/** - * @brief Remove a slice of the given string buffer. - * - * @param buf The string buffer to remove a slice. - * @param start The initial (inclusive) slice position to start - * removing, in bytes. - * @param end The final (non-inclusive) slice position to finish - * removing, in bytes. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function removes a slice of @p buf, starting at @p start - * (inclusive) and ending at @p end (non-inclusive). Both values are - * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. - */ - -EAPI Eina_Bool eina_strbuf_remove(Eina_Strbuf * buf, size_t start, - size_t end) EINA_ARG_NONNULL(1); - -/** - * @brief Retrieve a pointer to the contents of a string buffer - * - * @param buf The string buffer. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. The returned - * value must not be modified and will no longer be valid if @p buf is - * modified. In other words, any eina_strbuf_append() or similar will - * make that pointer invalid. - * - * @see eina_strbuf_string_steal() - */ -EAPI const char *eina_strbuf_string_get(const Eina_Strbuf * - buf) EINA_ARG_NONNULL(1) - EINA_WARN_UNUSED_RESULT; - -/** - * @brief Steal the contents of a string buffer. - * - * @param buf The string buffer to steal. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. @p buf is - * then initialized and does not own the returned string anymore. The - * caller must release the memory of the returned string by calling - * free(). - * - * @see eina_strbuf_string_get() - */ -EAPI char *eina_strbuf_string_steal(Eina_Strbuf * buf) -EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); - -/** - * @brief Free the contents of a string buffer but not the buffer. - * - * @param buf The string buffer to free the string of. - * - * This function frees the string contained in @p buf without freeing - * @p buf. - */ -EAPI void eina_strbuf_string_free(Eina_Strbuf * buf) EINA_ARG_NONNULL(1); - -/** - * @brief Retrieve the length of the string buffer content. - * - * @param buf The string buffer. - * @return The current length of the string, in bytes. - * - * This function returns the length of @p buf. - */ -EAPI size_t eina_strbuf_length_get(const Eina_Strbuf * - buf) EINA_ARG_NONNULL(1) - EINA_WARN_UNUSED_RESULT; - -EAPI Eina_Bool eina_strbuf_replace(Eina_Strbuf * buf, const char *str, - const char *with, - unsigned int n) EINA_ARG_NONNULL(1, 2, - 3); - -/** - * @def eina_strbuf_replace_first(buf, str, with) - * @brief Prepend the given character to the given buffer - * - * @param buf The string buffer to work with. - * @param str The string to replace. - * @param with The replaceing string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_strbuf_replace() with the n-th occurrence - * equal to @c 1. If @p buf can't replace it, #EINA_FALSE is returned, - * otherwise #EINA_TRUE is returned. - */ -#define eina_strbuf_replace_first(buf, str, with) eina_strbuf_replace(buf, str, with, 1) - -EAPI int eina_strbuf_replace_all(Eina_Strbuf * buf, const char *str, - const char *with) EINA_ARG_NONNULL(1, 2, - 3); - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_STRBUF_H */ diff --git a/tests/suite/ecore/src/include/eina_stringshare.h b/tests/suite/ecore/src/include/eina_stringshare.h deleted file mode 100644 index 88e27b60c3..0000000000 --- a/tests/suite/ecore/src/include/eina_stringshare.h +++ /dev/null @@ -1,107 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (C) 2008 Peter Wehrfritz - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies of the Software and its Copyright notices. In addition publicly - * documented acknowledgment must be given that this software has been used if no - * source code of this software is made available publicly. This includes - * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing - * documents or any documentation provided with any product containing this - * software. This License does not apply to any software that links to the - * libraries provided by this software (statically or dynamically), but only to - * the software provided. - * - * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice - * and it's intent. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef EINA_STRINGSHARE_H_ -#define EINA_STRINGSHARE_H_ - -#include <stdarg.h> - -#include "eina_types.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @defgroup Eina_Stringshare_Group Stringshare - * - * @{ - */ - -EAPI const char *eina_stringshare_add_length(const char *str, - unsigned int slen) - EINA_WARN_UNUSED_RESULT; -EAPI const char *eina_stringshare_add(const char *str) - EINA_WARN_UNUSED_RESULT; -EAPI const char *eina_stringshare_printf(const char *fmt, ...) -EINA_WARN_UNUSED_RESULT EINA_PRINTF(1, 2); -EAPI const char *eina_stringshare_vprintf(const char *fmt, - va_list args) - EINA_WARN_UNUSED_RESULT; -EAPI const char *eina_stringshare_nprintf(unsigned int len, - const char *fmt, ...) -EINA_WARN_UNUSED_RESULT EINA_PRINTF(2, 3); -EAPI const char *eina_stringshare_ref(const char *str); -EAPI void eina_stringshare_del(const char *str); -EAPI int eina_stringshare_strlen(const char *str) -EINA_PURE EINA_WARN_UNUSED_RESULT; -EAPI void eina_stringshare_dump(void); - -static inline Eina_Bool eina_stringshare_replace(const char **p_str, - const char *news) -EINA_ARG_NONNULL(1); -static inline Eina_Bool eina_stringshare_replace_length(const char **p_str, - const char *news, - unsigned int slen) -EINA_ARG_NONNULL(1); - -#include "eina_inline_stringshare.x" - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_STRINGSHARE_H_ */ diff --git a/tests/suite/ecore/src/include/eina_tiler.h b/tests/suite/ecore/src/include/eina_tiler.h deleted file mode 100644 index 9c23356855..0000000000 --- a/tests/suite/ecore/src/include/eina_tiler.h +++ /dev/null @@ -1,100 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_TILER_H_ -#define EINA_TILER_H_ - -#include "eina_types.h" -#include "eina_iterator.h" -#include "eina_rectangle.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @defgroup Eina_Tiler_Group Tiler - * - * @{ - */ - -/** - * @typedef Eina_Tiler - * Tiler type. - */ -typedef struct _Eina_Tiler Eina_Tiler; - -/** - * @typedef Eina_Tile_Grid_Info - * Grid type of a tiler. - */ -typedef struct Eina_Tile_Grid_Info Eina_Tile_Grid_Info; - -/** - * @struct Eina_Tile_Grid_Info - * Grid type of a tiler. - */ -struct Eina_Tile_Grid_Info { - unsigned long col; - /**< column of the tiler grid */ - unsigned long row; - /**< row of the tiler grid*/ - Eina_Rectangle rect; - /**< rectangle of the tiler grid*/ - Eina_Bool full; - /**< whether the grid is full or not */ -}; - -typedef struct _Eina_Tile_Grid_Slicer Eina_Tile_Grid_Slicer; - -EAPI Eina_Tiler *eina_tiler_new(int w, int h); -EAPI void eina_tiler_free(Eina_Tiler * t); -EAPI void eina_tiler_tile_size_set(Eina_Tiler * t, int w, int h); -EAPI Eina_Bool eina_tiler_rect_add(Eina_Tiler * t, - const Eina_Rectangle * r); -EAPI void eina_tiler_rect_del(Eina_Tiler * t, const Eina_Rectangle * r); -EAPI void eina_tiler_clear(Eina_Tiler * t); -EAPI Eina_Iterator *eina_tiler_iterator_new(const Eina_Tiler * t); -EAPI Eina_Iterator *eina_tile_grid_slicer_iterator_new(int x, int y, int w, - int h, int tile_w, - int tile_h); -static inline Eina_Bool eina_tile_grid_slicer_next(Eina_Tile_Grid_Slicer * - slc, - const - Eina_Tile_Grid_Info ** - rect); -static inline Eina_Bool eina_tile_grid_slicer_setup(Eina_Tile_Grid_Slicer * - slc, int x, int y, - int w, int h, - int tile_w, - int tile_h); - -#include "eina_inline_tiler.x" - - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_TILER_H_ */ diff --git a/tests/suite/ecore/src/include/eina_trash.h b/tests/suite/ecore/src/include/eina_trash.h deleted file mode 100644 index e3ceb7b41f..0000000000 --- a/tests/suite/ecore/src/include/eina_trash.h +++ /dev/null @@ -1,104 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Vincent Torri, Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_TRASH_H__ -#define EINA_TRASH_H__ - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_Trash_Group Trash - * - * @{ - */ - -/** - * @typedef Eina_Trash - * Type for a generic container of unused allocated pointer. - */ -typedef struct _Eina_Trash Eina_Trash; - -/** - * @struct _Eina_Trash - * Type for a generic container of unused allocated pointer. - */ -struct _Eina_Trash { - Eina_Trash *next; - /**< next item in trash. */ -}; - -static inline void eina_trash_init(Eina_Trash ** - trash) EINA_ARG_NONNULL(1); -static inline void eina_trash_push(Eina_Trash ** trash, - void *data) EINA_ARG_NONNULL(1); -static inline void *eina_trash_pop(Eina_Trash ** - trash) EINA_ARG_NONNULL(1) - EINA_WARN_UNUSED_RESULT; - -/** - * @def EINA_TRASH_CLEAN - * @brief Macro to remove all pointer from the trash. - * - * @param trash The trash to clean. - * @param data The pointer extracted from the trash. - * - * This macro allow the cleaning of @p trash in an easy way. It will - * remove all pointers from @p trash until it's empty. - * - * This macro can be used for freeing the data in the trash, like in - * the following example: - * - * @code - * Eina_Trash *trash = NULL; - * char *data; - * - * // trash is filled with pointer to some duped strings. - * - * EINA_TRASH_CLEAN(&trash, data) - * free(data); - * @endcode - * - * @note this macro is useful when you implement some memory pool. - */ -#define EINA_TRASH_CLEAN(trash, data) while ((data = eina_trash_pop(trash)) - -#include "eina_inline_trash.x" - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_TRASH_H_ */ diff --git a/tests/suite/ecore/src/include/eina_types.h b/tests/suite/ecore/src/include/eina_types.h deleted file mode 100644 index bde20a3f22..0000000000 --- a/tests/suite/ecore/src/include/eina_types.h +++ /dev/null @@ -1,285 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Carsten Haitzler, Vincent Torri, Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_TYPES_H_ -#define EINA_TYPES_H_ - -/** - * @addtogroup Eina_Core_Group Core - * - * @{ - */ - -/** - * @defgroup Eina_Types_Group Types - * - * @{ - */ - -#ifdef EAPI -#undef EAPI -#endif - -#ifdef _WIN32 -#ifdef EFL_EINA_BUILD -#ifdef DLL_EXPORT -#define EAPI __declspec(dllexport) -#else -#define EAPI -#endif /* ! DLL_EXPORT */ -#else -#define EAPI __declspec(dllimport) -#endif /* ! EFL_EINA_BUILD */ -#else -#ifdef __GNUC__ -#if __GNUC__ >= 4 -#define EAPI __attribute__ ((visibility("default"))) -#else -#define EAPI -#endif -#else -#define EAPI -#endif -#endif - -#include "eina_config.h" - -#ifdef EINA_WARN_UNUSED_RESULT -#undef EINA_WARN_UNUSED_RESULT -#endif -#ifdef EINA_ARG_NONNULL -#undef EINA_ARG_NONNULL -#endif -#ifdef EINA_DEPRECATED -#undef EINA_DEPRECATED -#endif -#ifdef EINA_MALLOC -#undef EINA_MALLOC -#endif -#ifdef EINA_PURE -#undef EINA_PURE -#endif -#ifdef EINA_PRINTF -#undef EINA_PRINTF -#endif -#ifdef EINA_SCANF -#undef EINA_SCANF -#endif -#ifdef EINA_FORMAT -#undef EINA_FORMAT -#endif -#ifdef EINA_CONST -#undef EINA_CONST -#endif -#ifdef EINA_NOINSTRUMENT -#undef EINA_NOINSTRUMENT -#endif -#ifdef EINA_UNLIKELY -#undef EINA_UNLIKELY -#endif -#ifdef EINA_LIKELY -#undef EINA_LIKELY -#endif - - -#ifdef __GNUC__ -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -#define EINA_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) -#else -#define EINA_WARN_UNUSED_RESULT -#endif - -#if (!defined(EINA_SAFETY_CHECKS)) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) -#define EINA_ARG_NONNULL(idx, ...) __attribute__ ((nonnull(idx, ## __VA_ARGS__))) -#else -#define EINA_ARG_NONNULL(idx, ...) -#endif - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -#define EINA_DEPRECATED __attribute__ ((__deprecated__)) -#else -#define EINA_DEPRECATED -#endif - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -#define EINA_MALLOC __attribute__ ((malloc)) -#define EINA_PURE __attribute__ ((pure)) -#else -#define EINA_MALLOC -#define EINA_PURE -#endif - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -#define EINA_PRINTF(fmt, arg) __attribute__((format (printf, fmt, arg))) -#define EINA_SCANF(fmt, arg) __attribute__((format (scanf, fmt, arg))) -#define EINA_FORMAT(fmt) __attribute__((format_arg(fmt))) -#define EINA_CONST __attribute__((const)) -#define EINA_NOINSTRUMENT __attribute__((no_instrument_function)) -#define EINA_UNLIKELY(exp) __builtin_expect((exp), 0) -#define EINA_LIKELY(exp) __builtin_expect((exp), 1) -#else -#define EINA_PRINTF(fmt, arg) -#define EINA_SCANF(fmt, arg) -#define EINA_FORMAT(fmt) -#define EINA_CONST -#define EINA_NOINSTRUMENT -#define EINA_UNLIKELY(exp) exp -#define EINA_LIKELY(exp) exp -#endif - -#elif defined(_WIN32) -#define EINA_WARN_UNUSED_RESULT -#define EINA_ARG_NONNULL(idx, ...) -#if defined(_MSC_VER) && _MSC_VER >= 1300 -#define EINA_DEPRECATED __declspec(deprecated) -#else -#define EINA_DEPRECATED -#endif -#define EINA_MALLOC -#define EINA_PURE -#define EINA_PRINTF(fmt, arg) -#define EINA_SCANF(fmt, arg) -#define EINA_FORMAT(fmt) -#define EINA_CONST -#define EINA_NOINSTRUMENT -#define EINA_UNLIKELY(exp) exp -#define EINA_LIKELY(exp) exp - -#elif defined(__SUNPRO_C) -#define EINA_WARN_UNUSED_RESULT -#define EINA_ARG_NONNULL(...) -#define EINA_DEPRECATED -#if __SUNPRO_C >= 0x590 -#define EINA_MALLOC __attribute__ ((malloc)) -#define EINA_PURE __attribute__ ((pure)) -#else -#define EINA_MALLOC -#define EINA_PURE -#endif -#define EINA_PRINTF(fmt, arg) -#define EINA_SCANF(fmt, arg) -#define EINA_FORMAT(fmt) -#if __SUNPRO_C >= 0x590 -#define EINA_CONST __attribute__ ((const)) -#else -#define EINA_CONST -#endif -#define EINA_NOINSTRUMENT -#define EINA_UNLIKELY(exp) exp -#define EINA_LIKELY(exp) exp - -#else /* ! __GNUC__ && ! _WIN32 && ! __SUNPRO_C */ - -/** - * @def EINA_WARN_UNUSED_RESULT - * Used to warn when the returned value of the function is not used. - */ -#define EINA_WARN_UNUSED_RESULT - -/** - * @def EINA_ARG_NONNULL - * Used to warn when the specified arguments of the function are @c NULL. - */ -#define EINA_ARG_NONNULL(idx, ...) - -/** - * @def EINA_DEPRECATED - * Used to warn when the function is considered as deprecated. - */ -#define EINA_DEPRECATED -#define EINA_MALLOC -#define EINA_PURE -#define EINA_PRINTF(fmt, arg) -#define EINA_SCANF(fmt, arg) -#define EINA_FORMAT(fmt) -#define EINA_CONST -#define EINA_NOINSTRUMENT -#define EINA_UNLIKELY(exp) exp -#define EINA_LIKELY(exp) exp -#endif /* ! __GNUC__ && ! _WIN32 && ! __SUNPRO_C */ - - -/** - * @typedef Eina_Bool - * Type to mimic a boolean. - * - * @note it differs from stdbool.h as this is defined as an unsigned - * char to make it usable by bitfields (Eina_Bool name:1) and - * also take as few bytes as possible. - */ -typedef unsigned char Eina_Bool; - -/** - * @def EINA_FALSE - * boolean value FALSE (numerical value 0) - */ -#define EINA_FALSE ((Eina_Bool)0) - -/** - * @def EINA_TRUE - * boolean value TRUE (numerical value 1) - */ -#define EINA_TRUE ((Eina_Bool)1) - -EAPI extern const unsigned int eina_prime_table[]; - -/** - * @typedef Eina_Compare_Cb - * Function used in functions using sorting. It compares @p data1 and - * @p data2. If @p data1 is 'less' than @p data2, -1 must be returned, - * if it is 'greater', 1 must be returned, and if they are equal, 0 - * must be returned. - */ -typedef int (*Eina_Compare_Cb) (const void *data1, const void *data2); - -/** - * @def EINA_COMPARE_CB - * Macro to cast to Eina_Compare_Cb. - */ -#define EINA_COMPARE_CB(function) ((Eina_Compare_Cb)function) - -typedef Eina_Bool(*Eina_Each_Cb) (const void *container, void *data, - void *fdata); - -/** - * @def EINA_EACH_CB - * Macro to cast to Eina_Each. - */ -#define EINA_EACH_CB(Function) ((Eina_Each_Cb)Function) - -/** - * @typedef Eina_Free_Cb - * A callback type used to free data when iterating over a container. - */ -typedef void (*Eina_Free_Cb) (void *data); - -/** - * @def EINA_FREE_CB - * Macro to cast to Eina_Free_Cb. - */ -#define EINA_FREE_CB(Function) ((Eina_Free_Cb)Function) - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_TYPES_H_ */ diff --git a/tests/suite/ecore/src/include/eina_unicode.h b/tests/suite/ecore/src/include/eina_unicode.h deleted file mode 100644 index 4cd362fcb5..0000000000 --- a/tests/suite/ecore/src/include/eina_unicode.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef EINA_UNICODE_H -#define EINA_UNICODE_H - -#include <stdlib.h> - -#include "eina_config.h" -#include "eina_types.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ -/** - * @addtogroup Eina_Unicode_String Unicode String - * - * @brief These functions provide basic unicode string handling - * - * Eina_Unicode is a type that holds unicode codepoints. - * - * @{ - */ - -/** - * @typedef Eina_Unicode - * A type that holds Unicode codepoints. - */ -#if EINA_SIZEOF_WCHAR_T >= 4 -#include <wchar.h> -typedef wchar_t Eina_Unicode; -#elif defined(EINA_HAVE_INTTYPES_H) -#include <inttypes.h> -typedef uint32_t Eina_Unicode; -#elif defined(EINA_HAVE_STDINT_H) -#include <stdint.h> -typedef uint32_t Eina_Unicode; -#else -/* Hope that int is big enough */ -typedef unsigned int Eina_Unicode; -#endif - -EAPI extern const Eina_Unicode *EINA_UNICODE_EMPTY_STRING; - -EAPI size_t eina_unicode_strlen(const Eina_Unicode * - ustr) EINA_ARG_NONNULL(1) -EINA_WARN_UNUSED_RESULT EINA_PURE; -EAPI size_t eina_unicode_strnlen(const Eina_Unicode * ustr, - int n) EINA_ARG_NONNULL(1) -EINA_WARN_UNUSED_RESULT EINA_PURE; - - -EAPI Eina_Unicode *eina_unicode_strdup(const Eina_Unicode * text) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; - -EAPI int eina_unicode_strcmp(const Eina_Unicode * a, - const Eina_Unicode * b) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_PURE; - -EAPI Eina_Unicode *eina_unicode_strcpy(Eina_Unicode * dest, - const Eina_Unicode * - source) EINA_ARG_NONNULL(1, 2); - -EAPI Eina_Unicode *eina_unicode_strstr(const Eina_Unicode * haystack, - const Eina_Unicode * needle) -EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_PURE; - -EAPI Eina_Unicode *eina_unicode_strncpy(Eina_Unicode * dest, - const Eina_Unicode * source, - size_t n) EINA_ARG_NONNULL(1, 2); - -EAPI Eina_Unicode *eina_unicode_escape(const Eina_Unicode * - str) EINA_ARG_NONNULL(1) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; - -/** - * @} - */ -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/include/eina_ustrbuf.h b/tests/suite/ecore/src/include/eina_ustrbuf.h deleted file mode 100644 index 5a24ccda67..0000000000 --- a/tests/suite/ecore/src/include/eina_ustrbuf.h +++ /dev/null @@ -1,445 +0,0 @@ -#ifndef EINA_USTRBUF_H -#define EINA_USTRBUF_H - -#include <stddef.h> - -#include "eina_types.h" -#include "eina_unicode.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @defgroup Eina_Unicode_String_Buffer_Group Unicode String Buffer - * - * @{ - */ - -/** - * @typedef Eina_UStrbuf - * Type for a string buffer. - */ -typedef struct _Eina_Strbuf Eina_UStrbuf; - -/** - * @brief Create a new string buffer. - * - * @return Newly allocated string buffer instance. - * - * This function creates a new string buffer. On error, @c NULL is - * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To - * free the resources, use eina_ustrbuf_free(). - * - * @see eina_ustrbuf_free() - * @see eina_ustrbuf_append() - * @see eina_ustrbuf_string_get() - */ -EAPI Eina_UStrbuf *eina_ustrbuf_new(void) -EINA_MALLOC EINA_WARN_UNUSED_RESULT; - -/** - * @brief Free a string buffer. - * - * @param buf The string buffer to free. - * - * This function frees the memory of @p buf. @p buf must have been - * created by eina_ustrbuf_new(). - */ -EAPI void eina_ustrbuf_free(Eina_UStrbuf * buf) EINA_ARG_NONNULL(1); - -/** - * @brief Reset a string buffer. - * - * @param buf The string buffer to reset. - * - * This function reset @p buf: the buffer len is set to 0, and the - * string is set to '\\0'. No memory is free'd. - */ -EAPI void eina_ustrbuf_reset(Eina_UStrbuf * buf) EINA_ARG_NONNULL(1); - -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. It computes the length of - * @p str, so is slightly slower than eina_ustrbuf_append_length(). If - * the length is known beforehand, consider using that variant. If - * @p buf can't append it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - * - * @see eina_ustrbuf_append() - * @see eina_ustrbuf_append_length() - */ -EAPI Eina_Bool eina_ustrbuf_append(Eina_UStrbuf * buf, - const Eina_Unicode * - str) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Append an escaped string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends the escaped string @p str to @p buf. If @p - * str can not be appended, #EINA_FALSE is returned, otherwise, - * #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_ustrbuf_append_escaped(Eina_UStrbuf * buf, - const Eina_Unicode * - str) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Append a string to a buffer, reallocating as necessary, - * limited by the given length. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param maxlen The maximum number of characters to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends at most @p maxlen characters of @p str to - * @p buf. It can't appends more than the length of @p str. It - * computes the length of @p str, so is slightly slower than - * eina_ustrbuf_append_length(). If the length is known beforehand, - * consider using that variant (@p maxlen should then be checked so - * that it is greater than the size of @p str). If @p str can not be - * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is - * returned. - * - * @see eina_ustrbuf_append() - * @see eina_ustrbuf_append_length() - */ -EAPI Eina_Bool eina_ustrbuf_append_n(Eina_UStrbuf * buf, - const Eina_Unicode * str, - size_t maxlen) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Append a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param length The exact length to use. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_ustrbuf_append() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_ustrbuf_append() - * @see eina_ustrbuf_append_n() - */ -EAPI Eina_Bool eina_ustrbuf_append_length(Eina_UStrbuf * buf, - const Eina_Unicode * str, - size_t length) -EINA_ARG_NONNULL(1, 2); - -/** - * @brief Append a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to append to. - * @param c The char to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf. If it can not insert it, - * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_ustrbuf_append_char(Eina_UStrbuf * buf, - Eina_Unicode c) -EINA_ARG_NONNULL(1); - -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param str The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf at position @p pos. It - * computes the length of @p str, so is slightly slower than - * eina_ustrbuf_insert_length(). If the length is known beforehand, - * consider using that variant. If @p buf can't insert it, #EINA_FALSE - * is returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_ustrbuf_insert(Eina_UStrbuf * buf, - const Eina_Unicode * str, - size_t pos) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Insert an escaped string to a buffer, reallocating as - * necessary. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts the escaped string @p str to @p buf at - * position @p pos. If @p buf can't insert @p str, #EINA_FALSE is - * returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_ustrbuf_insert_escaped(Eina_UStrbuf * buf, - const Eina_Unicode * str, - size_t pos) EINA_ARG_NONNULL(1, - 2); - -/** - * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param maxlen The maximum number of chars to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str ot @p buf at position @p pos, with at - * most @p maxlen bytes. The number of inserted characters can not be - * greater than the length of @p str. It computes the length of - * @p str, so is slightly slower than eina_ustrbuf_insert_length(). If the - * length is known beforehand, consider using that variant (@p maxlen - * should then be checked so that it is greater than the size of - * @p str). If @p str can not be inserted, #EINA_FALSE is returned, - * otherwise, #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_ustrbuf_insert_n(Eina_UStrbuf * buf, - const Eina_Unicode * str, - size_t maxlen, - size_t pos) EINA_ARG_NONNULL(1, 2); - -/** - * @brief Insert a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param length The exact length to use. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_ustrbuf_insert() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_ustrbuf_insert() - * @see eina_ustrbuf_insert_n() - */ -EAPI Eina_Bool eina_ustrbuf_insert_length(Eina_UStrbuf * buf, - const Eina_Unicode * str, - size_t length, - size_t pos) EINA_ARG_NONNULL(1, - 2); - -/** - * @brief Insert a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to insert to. - * @param c The char to insert. - * @param pos The position to insert the char. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf at position @p pos. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -EAPI Eina_Bool eina_ustrbuf_insert_char(Eina_UStrbuf * buf, Eina_Unicode c, - size_t pos) EINA_ARG_NONNULL(1); - -/** - * @def eina_ustrbuf_prepend(buf, str) - * @brief Prepend the given string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_ustrbuf_insert() at position 0.If @p buf - * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -#define eina_ustrbuf_prepend(buf, str) eina_ustrbuf_insert(buf, str, 0) - -/** - * @def eina_ustrbuf_prepend_escaped(buf, str) - * @brief Prepend the given escaped string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_ustrbuf_insert_escaped() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_ustrbuf_prepend_escaped(buf, str) eina_ustrbuf_insert_escaped(buf, str, 0) - -/** - * @def eina_ustrbuf_prepend_n(buf, str) - * @brief Prepend the given escaped string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @param maxlen The maximum number of Eina_Unicode *s to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_ustrbuf_insert_n() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_ustrbuf_prepend_n(buf, str, maxlen) eina_ustrbuf_insert_n(buf, str, maxlen, 0) - -/** - * @def eina_ustrbuf_prepend_length(buf, str) - * @brief Prepend the given escaped string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param str The string to prepend. - * @param length The exact length to use. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_ustrbuf_insert_length() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_ustrbuf_prepend_length(buf, str, length) eina_ustrbuf_insert_length(buf, str, length, 0) - -/** - * @def eina_ustrbuf_prepend_Eina_Unicode *(buf, str) - * @brief Prepend the given Eina_Unicode *acter to the given buffer - * - * @param buf The string buffer to prepend to. - * @param c The Eina_Unicode *acter to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_ustrbuf_insert_Eina_Unicode *() at position 0. If - * @p buf can't prepend it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - */ -#define eina_ustrbuf_prepend_Eina_Unicode *(buf, c)eina_ustrbuf_insert_Eina_Unicode * (buf, c, 0) - -/** - * @def eina_ustrbuf_prepend_printf(buf, fmt, ...) - * @brief Prepend the given string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param fmt The string to prepend. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_ustrbuf_insert_printf() at position 0.If @p buf - * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -#define eina_ustrbuf_prepend_printf(buf, fmt, ...) eina_ustrbuf_insert_printf(buf, fmt, 0, ## __VA_ARGS__) - -/** - * @def eina_ustrbuf_prepend_vprintf(buf, fmt, args) - * @brief Prepend the given string to the given buffer - * - * @param buf The string buffer to prepend to. - * @param fmt The string to prepend. - * @param args The variable arguments. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This macro is calling eina_ustrbuf_insert_vprintf() at position 0.If @p buf - * can't prepend it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -#define eina_ustrbuf_prepend_vprintf(buf, fmt, args) eina_ustrbuf_insert_vprintf(buf, fmt, 0, args) - -/** - * @brief Remove a slice of the given string buffer. - * - * @param buf The string buffer to remove a slice. - * @param start The initial (inclusive) slice position to start - * removing, in bytes. - * @param end The final (non-inclusive) slice position to finish - * removing, in bytes. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function removes a slice of @p buf, starting at @p start - * (inclusive) and ending at @p end (non-inclusive). Both values are - * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_ustrbuf_remove(Eina_UStrbuf * buf, size_t start, - size_t end) EINA_ARG_NONNULL(1); - -/** - * @brief Retrieve a pointer to the contents of a string buffer - * - * @param buf The string buffer. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. The returned - * value must not be modified and will no longer be valid if @p buf is - * modified. In other words, any eina_ustrbuf_append() or similar will - * make that pointer invalid. - * - * @see eina_ustrbuf_string_steal() - */ -EAPI const Eina_Unicode *eina_ustrbuf_string_get(const Eina_UStrbuf * - buf) EINA_ARG_NONNULL(1) - EINA_WARN_UNUSED_RESULT; - -/** - * @brief Steal the contents of a string buffer. - * - * @param buf The string buffer to steal. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. @p buf is - * then initialized and does not own the returned string anymore. The - * caller must release the memory of the returned string by calling - * free(). - * - * @see eina_ustrbuf_string_get() - */ -EAPI Eina_Unicode *eina_ustrbuf_string_steal(Eina_UStrbuf * buf) -EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); - -/** - * @brief Free the contents of a string buffer but not the buffer. - * - * @param buf The string buffer to free the string of. - * - * This function frees the string contained in @p buf without freeing - * @p buf. - */ -EAPI void eina_ustrbuf_string_free(Eina_UStrbuf * buf) EINA_ARG_NONNULL(1); - -/** - * @brief Retrieve the length of the string buffer content. - * - * @param buf The string buffer. - * @return The current length of the string, in bytes. - * - * This function returns the length of @p buf. - */ -EAPI size_t -eina_ustrbuf_length_get(const Eina_UStrbuf * - buf) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_STRBUF_H */ diff --git a/tests/suite/ecore/src/include/eina_ustringshare.h b/tests/suite/ecore/src/include/eina_ustringshare.h deleted file mode 100644 index 60f83f2f56..0000000000 --- a/tests/suite/ecore/src/include/eina_ustringshare.h +++ /dev/null @@ -1,104 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (C) 2008 Peter Wehrfritz - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies of the Software and its Copyright notices. In addition publicly - * documented acknowledgment must be given that this software has been used if no - * source code of this software is made available publicly. This includes - * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing - * documents or any documentation provided with any product containing this - * software. This License does not apply to any software that links to the - * libraries provided by this software (statically or dynamically), but only to - * the software provided. - * - * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice - * and it's intent. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef EINA_USTRINGSHARE_H_ -#define EINA_USTRINGSHARE_H_ - -#include "eina_types.h" -#include "eina_unicode.h" - -/** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @defgroup Eina_UStringshare_Group Unicode Stringshare - * - * @{ - */ - -EAPI const Eina_Unicode *eina_ustringshare_add_length(const Eina_Unicode * - str, - unsigned int slen) - EINA_WARN_UNUSED_RESULT; -EAPI const Eina_Unicode *eina_ustringshare_add(const Eina_Unicode * - str) - EINA_WARN_UNUSED_RESULT; -EAPI const Eina_Unicode *eina_ustringshare_ref(const Eina_Unicode * str); -EAPI void eina_ustringshare_del(const Eina_Unicode * str); -EAPI int eina_ustringshare_strlen(const Eina_Unicode * str) -EINA_PURE EINA_WARN_UNUSED_RESULT; -EAPI void eina_ustringshare_dump(void); - -static inline Eina_Bool eina_ustringshare_replace(const Eina_Unicode ** - p_str, - const Eina_Unicode * - news) -EINA_ARG_NONNULL(1); -static inline Eina_Bool eina_ustringshare_replace_length(const Eina_Unicode - ** p_str, - const Eina_Unicode - * news, - unsigned int slen) -EINA_ARG_NONNULL(1); - -#include "eina_inline_ustringshare.x" - -/** - * @} - */ - -/** - * @} - */ - -#endif /* EINA_STRINGSHARE_H_ */ diff --git a/tests/suite/ecore/src/lib/Ecore.h b/tests/suite/ecore/src/lib/Ecore.h deleted file mode 100644 index 2c939a688b..0000000000 --- a/tests/suite/ecore/src/lib/Ecore.h +++ /dev/null @@ -1,621 +0,0 @@ -#ifndef _ECORE_H -#define _ECORE_H - -#ifdef _MSC_VER -#include <Evil.h> -#endif - -#include <Eina.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.h - * @brief The file that provides the program utility, main loop and timer - * functions. - * - * This header provides the Ecore event handling loop. For more - * details, see @ref Ecore_Main_Loop_Group. - * - * For the main loop to be of any use, you need to be able to add events - * and event handlers. Events for file descriptor events are covered in - * @ref Ecore_FD_Handler_Group. - * - * Time functions are covered in @ref Ecore_Time_Group. - * - * There is also provision for callbacks for when the loop enters or - * exits an idle state. See @ref Idle_Group for more information. - * - * Functions are also provided for spawning child processes using fork. - * See @ref Ecore_Exe_Basic_Group and @ref Ecore_Exe_Signal_Group for - * more details. - */ - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <sys/select.h> -#include <signal.h> -#endif - -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define ECORE_VERSION_MAJOR 1 -#define ECORE_VERSION_MINOR 0 - - typedef struct _Ecore_Version { - int major; - int minor; - int micro; - int revision; - } Ecore_Version; - - EAPI extern Ecore_Version *ecore_version; - -#define ECORE_CALLBACK_CANCEL EINA_FALSE /**< Return value to remove a callback */ -#define ECORE_CALLBACK_RENEW EINA_TRUE /**< Return value to keep a callback */ - -#define ECORE_CALLBACK_PASS_ON EINA_TRUE /**< Return value to pass event to next handler */ -#define ECORE_CALLBACK_DONE EINA_FALSE /**< Return value to stop event handling */ - -#define ECORE_EVENT_NONE 0 -#define ECORE_EVENT_SIGNAL_USER 1 /**< User signal event */ -#define ECORE_EVENT_SIGNAL_HUP 2 /**< Hup signal event */ -#define ECORE_EVENT_SIGNAL_EXIT 3 /**< Exit signal event */ -#define ECORE_EVENT_SIGNAL_POWER 4 /**< Power signal event */ -#define ECORE_EVENT_SIGNAL_REALTIME 5 /**< Realtime signal event */ -#define ECORE_EVENT_COUNT 6 - -#define ECORE_EXE_PRIORITY_INHERIT 9999 - - EAPI extern int ECORE_EXE_EVENT_ADD; - /**< A child process has been added */ - EAPI extern int ECORE_EXE_EVENT_DEL; - /**< A child process has been deleted (it exited, naming consistent with the rest of ecore). */ - EAPI extern int ECORE_EXE_EVENT_DATA; - /**< Data from a child process. */ - EAPI extern int ECORE_EXE_EVENT_ERROR; - /**< Errors from a child process. */ - - enum _Ecore_Fd_Handler_Flags { - ECORE_FD_READ = 1, - /**< Fd Read mask */ - ECORE_FD_WRITE = 2, - /**< Fd Write mask */ - ECORE_FD_ERROR = 4 - /**< Fd Error mask */ - }; - typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags; - - enum _Ecore_Exe_Flags { /* flags for executing a child with its stdin and/or stdout piped back */ - ECORE_EXE_PIPE_READ = 1, - /**< Exe Pipe Read mask */ - ECORE_EXE_PIPE_WRITE = 2, - /**< Exe Pipe Write mask */ - ECORE_EXE_PIPE_ERROR = 4, - /**< Exe Pipe error mask */ - ECORE_EXE_PIPE_READ_LINE_BUFFERED = 8, - /**< Reads are buffered until a newline and delivered 1 event per line */ - ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, - /**< Errors are buffered until a newline and delivered 1 event per line */ - ECORE_EXE_PIPE_AUTO = 32, - /**< stdout and stderr are buffered automatically */ - ECORE_EXE_RESPAWN = 64, - /**< FIXME: Exe is restarted if it dies */ - ECORE_EXE_USE_SH = 128, - /**< Use /bin/sh to run the command. */ - ECORE_EXE_NOT_LEADER = 256 - /**< Do not use setsid() to have the executed process be its own session leader */ - }; - typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags; - - enum _Ecore_Exe_Win32_Priority { - ECORE_EXE_WIN32_PRIORITY_IDLE, - /**< Idle priority, for monitoring the system */ - ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL, - /**< Below default priority */ - ECORE_EXE_WIN32_PRIORITY_NORMAL, - /**< Default priority */ - ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL, - /**< Above default priority */ - ECORE_EXE_WIN32_PRIORITY_HIGH, - /**< High priority, use with care as other threads in the system will not get processor time */ - ECORE_EXE_WIN32_PRIORITY_REALTIME - /**< Realtime priority, should be almost never used as it can interrupt system threads that manage mouse input, keyboard input, and background disk flushing */ - }; - typedef enum _Ecore_Exe_Win32_Priority Ecore_Exe_Win32_Priority; - - enum _Ecore_Poller_Type { /* Poller types */ - ECORE_POLLER_CORE = 0 - /**< The core poller interval */ - }; - typedef enum _Ecore_Poller_Type Ecore_Poller_Type; - - typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */ - typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */ - typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */ - typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; /**< A handle for idle enterers */ - typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; /**< A handle for idle exiters */ - typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for Fd handlers */ - typedef struct _Ecore_Win32_Handler Ecore_Win32_Handler; /**< A handle for HANDLE handlers on Windows */ - typedef struct _Ecore_Event_Handler Ecore_Event_Handler; /**< A handle for an event handler */ - typedef struct _Ecore_Event_Filter Ecore_Event_Filter; /**< A handle for an event filter */ - typedef struct _Ecore_Event Ecore_Event; /**< A handle for an event */ - typedef struct _Ecore_Animator Ecore_Animator; /**< A handle for animators */ - typedef struct _Ecore_Pipe Ecore_Pipe; /**< A handle for pipes */ - typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */ - typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User;/**< User signal event */ - typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */ - typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit;/**< Exit signal event */ - typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; - /**< Power signal event */ - typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; - /**< Realtime signal event */ - typedef struct _Ecore_Exe_Event_Add Ecore_Exe_Event_Add; /**< Spawned Exe add event */ - typedef struct _Ecore_Exe_Event_Del Ecore_Exe_Event_Del; /**< Spawned Exe exit event */ - typedef struct _Ecore_Exe_Event_Data_Line Ecore_Exe_Event_Data_Line; - /**< Lines from a child process */ - typedef struct _Ecore_Exe_Event_Data Ecore_Exe_Event_Data; /**< Data from a child process */ - typedef struct _Ecore_Thread Ecore_Thread; - - /** - * @typedef Ecore_Data_Cb Ecore_Data_Cb - * A callback which is used to return data to the main function - */ - typedef void *(*Ecore_Data_Cb) (void *data); - /** - * @typedef Ecore_Filter_Cb - * A callback used for filtering events from the main loop. - */ - typedef Eina_Bool(*Ecore_Filter_Cb) (void *data, void *loop_data, - int type, void *event); - /** - * @typedef Ecore_Eselect_Function Ecore_Eselect_Function - * A function which can be used to replace select() in the main loop - */ - typedef int (*Ecore_Select_Function) (int nfds, fd_set * readfds, - fd_set * writefds, - fd_set * exceptfds, - struct timeval * timeout); - /** - * @typedef Ecore_End_Cb Ecore_End_Cb - * This is the callback which is called at the end of a function, usually for cleanup purposes. - */ - typedef void (*Ecore_End_Cb) (void *user_data, void *func_data); - /** - * @typedef Ecore_Pipe_Cb Ecore_Pipe_Cb - * The callback that data written to the pipe is sent to. - */ - typedef void (*Ecore_Pipe_Cb) (void *data, void *buffer, - unsigned int nbyte); - /** - * @typedef Ecore_Exe_Cb Ecore_Exe_Cb - * A callback to run with the associated @ref Ecore_Exe, usually for cleanup purposes. - */ - typedef void (*Ecore_Exe_Cb) (void *data, const Ecore_Exe * exe); - /** - * @typedef Ecore_Event_Handler_Cb Ecore_Event_Handler_Cb - * A callback used by the main loop to handle events of a specified type. - */ - typedef Eina_Bool(*Ecore_Event_Handler_Cb) (void *data, int type, - void *event); - /** - * @typedef Ecore_Thread_Heavy_Cb Ecore_Thread_Heavy_Cb - * A callback used to run cpu intensive or blocking I/O operations. - */ - typedef void (*Ecore_Thread_Heavy_Cb) (Ecore_Thread * thread, - void *data); - /** - * @typedef Ecore_Thread_Notify_Cb Ecore_Thread_Notify_Cb - * A callback used by the main loop to receive data sent by an @ref Ecore_Thread. - */ - typedef void (*Ecore_Thread_Notify_Cb) (Ecore_Thread * thread, - void *msg_data, - void *data); - /** - * @typedef Ecore_Task_Cb Ecore_Task_Cb - * A callback run for a task (timer, idler, poller, animater, etc) - */ - typedef Eina_Bool(*Ecore_Task_Cb) (void *data); - /** - * @typedef Ecore_Cb Ecore_Cb - * A generic callback called as a hook when a certain point in execution is reached. - */ - typedef void (*Ecore_Cb) (void *data); - /** - * @typedef Ecore_Fd_Cb Ecore_Fd_Cb - * A callback used by an @ref Ecore_Fd_Handler. - */ - typedef Eina_Bool(*Ecore_Fd_Cb) (void *data, - Ecore_Fd_Handler * fd_handler); - /** - * @typedef Ecore_Fd_Prep_Cb Ecore_Fd_Prep_Cb - * A callback used by an @ref Ecore_Fd_Handler. - */ - typedef void (*Ecore_Fd_Prep_Cb) (void *data, - Ecore_Fd_Handler * fd_handler); - /** - * @typedef Ecore_Fd_Win32_Cb Ecore_Fd_Win32_Cb - * A callback used by an @ref Ecore_Win32_Handler. - */ - typedef Eina_Bool(*Ecore_Fd_Win32_Cb) (void *data, - Ecore_Win32_Handler * wh); - - - typedef struct _Ecore_Job Ecore_Job; - /**< A job handle */ - - struct _Ecore_Event_Signal_User { -/** User signal event */ - int number; - /**< The signal number. Either 1 or 2 */ - void *ext_data; - /**< Extension data - not used */ - -#ifndef _WIN32 - siginfo_t data; - /**< Signal info */ -#endif - }; - - struct _Ecore_Event_Signal_Hup { -/** Hup signal event */ - void *ext_data; - /**< Extension data - not used */ - -#ifndef _WIN32 - siginfo_t data; - /**< Signal info */ -#endif - }; - - struct _Ecore_Event_Signal_Exit { -/** Exit request event */ - unsigned int interrupt:1; - /**< Set if the exit request was an interrupt signal*/ - unsigned int quit:1; /**< set if the exit request was a quit signal */ - unsigned int terminate:1; - /**< Set if the exit request was a terminate singal */ - void *ext_data; /**< Extension data - not used */ - -#ifndef _WIN32 - siginfo_t data; - /**< Signal info */ -#endif - }; - - struct _Ecore_Event_Signal_Power { -/** Power event */ - void *ext_data; - /**< Extension data - not used */ - -#ifndef _WIN32 - siginfo_t data; - /**< Signal info */ -#endif - }; - - struct _Ecore_Event_Signal_Realtime { -/** Realtime event */ - int num; - /**< The realtime signal's number */ - -#ifndef _WIN32 - siginfo_t data; - /**< Signal info */ -#endif - }; - - struct _Ecore_Exe_Event_Add { -/** Process add event */ - Ecore_Exe *exe; - /**< The handle to the added process */ - void *ext_data; - /**< Extension data - not used */ - }; - - struct _Ecore_Exe_Event_Del { -/** Process exit event */ - pid_t pid; /**< The process ID of the process that exited */ - int exit_code; /**< The exit code of the process */ - Ecore_Exe *exe; - /**< The handle to the exited process, or NULL if not found */ - int exit_signal; /** < The signal that caused the process to exit */ - unsigned int exited:1; - /** < set to 1 if the process exited of its own accord */ - unsigned int signalled:1; - /** < set to 1 id the process exited due to uncaught signal */ - void *ext_data; /**< Extension data - not used */ -#ifndef _WIN32 - siginfo_t data; - /**< Signal info */ -#endif - }; - - struct _Ecore_Exe_Event_Data_Line { -/**< Lines from a child process */ - char *line; - int size; - }; - - struct _Ecore_Exe_Event_Data { -/** Data from a child process event */ - Ecore_Exe *exe; - /**< The handle to the process */ - void *data; - /**< the raw binary data from the child process that was received */ - int size; - /**< the size of this data in bytes */ - Ecore_Exe_Event_Data_Line *lines; - /**< an array of line data if line buffered, the last one has it's line member set to NULL */ - }; - - EAPI int ecore_init(void); - EAPI int ecore_shutdown(void); - - EAPI void ecore_app_args_set(int argc, const char **argv); - EAPI void ecore_app_args_get(int *argc, char ***argv); - EAPI void ecore_app_restart(void); - - EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, - Ecore_Event_Handler_Cb - func, - const void - *data); - EAPI void *ecore_event_handler_del(Ecore_Event_Handler * - event_handler); - EAPI Ecore_Event *ecore_event_add(int type, void *ev, - Ecore_End_Cb func_free, - void *data); - EAPI void *ecore_event_del(Ecore_Event * event); - EAPI int ecore_event_type_new(void); - EAPI Ecore_Event_Filter *ecore_event_filter_add(Ecore_Data_Cb - func_start, - Ecore_Filter_Cb - func_filter, - Ecore_End_Cb - func_end, - const void *data); - EAPI void *ecore_event_filter_del(Ecore_Event_Filter * ef); - EAPI int ecore_event_current_type_get(void); - EAPI void *ecore_event_current_event_get(void); - - - EAPI void ecore_exe_run_priority_set(int pri); - EAPI int ecore_exe_run_priority_get(void); - EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, - const void *data); - EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, - Ecore_Exe_Flags flags, - const void *data); - EAPI void ecore_exe_callback_pre_free_set(Ecore_Exe * exe, - Ecore_Exe_Cb func); - EAPI Eina_Bool ecore_exe_send(Ecore_Exe * exe, const void *data, - int size); - EAPI void ecore_exe_close_stdin(Ecore_Exe * exe); - EAPI void ecore_exe_auto_limits_set(Ecore_Exe * exe, - int start_bytes, int end_bytes, - int start_lines, - int end_lines); - EAPI Ecore_Exe_Event_Data *ecore_exe_event_data_get(Ecore_Exe * - exe, - Ecore_Exe_Flags - flags); - EAPI void ecore_exe_event_data_free(Ecore_Exe_Event_Data * data); - EAPI void *ecore_exe_free(Ecore_Exe * exe); - EAPI pid_t ecore_exe_pid_get(const Ecore_Exe * exe); - EAPI void ecore_exe_tag_set(Ecore_Exe * exe, const char *tag); - EAPI const char *ecore_exe_tag_get(const Ecore_Exe * exe); - EAPI const char *ecore_exe_cmd_get(const Ecore_Exe * exe); - EAPI void *ecore_exe_data_get(const Ecore_Exe * exe); - EAPI Ecore_Exe_Flags ecore_exe_flags_get(const Ecore_Exe * exe); - EAPI void ecore_exe_pause(Ecore_Exe * exe); - EAPI void ecore_exe_continue(Ecore_Exe * exe); - EAPI void ecore_exe_interrupt(Ecore_Exe * exe); - EAPI void ecore_exe_quit(Ecore_Exe * exe); - EAPI void ecore_exe_terminate(Ecore_Exe * exe); - EAPI void ecore_exe_kill(Ecore_Exe * exe); - EAPI void ecore_exe_signal(Ecore_Exe * exe, int num); - EAPI void ecore_exe_hup(Ecore_Exe * exe); - - EAPI Ecore_Idler *ecore_idler_add(Ecore_Task_Cb func, - const void *data); - EAPI void *ecore_idler_del(Ecore_Idler * idler); - - EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(Ecore_Task_Cb func, - const void *data); - EAPI Ecore_Idle_Enterer - *ecore_idle_enterer_before_add(Ecore_Task_Cb func, - const void *data); - EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer * - idle_enterer); - - EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, - const void *data); - EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter * idle_exiter); - - EAPI void ecore_main_loop_iterate(void); - - EAPI void ecore_main_loop_select_func_set(Ecore_Select_Function - func); - EAPI void *ecore_main_loop_select_func_get(void); - - EAPI Eina_Bool ecore_main_loop_glib_integrate(void); - EAPI void ecore_main_loop_glib_always_integrate_disable(void); - - EAPI void ecore_main_loop_begin(void); - EAPI void ecore_main_loop_quit(void); - EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, - Ecore_Fd_Handler_Flags - flags, - Ecore_Fd_Cb func, - const void *data, - Ecore_Fd_Cb - buf_func, - const void - *buf_data); - EAPI void - ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler * - fd_handler, - Ecore_Fd_Prep_Cb - func, - const void *data); - EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler * - fd_handler); - EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler * - fd_handler); - EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler * - fd_handler, - Ecore_Fd_Handler_Flags - flags); - EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler * - fd_handler, - Ecore_Fd_Handler_Flags - flags); - - EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, - Ecore_Fd_Win32_Cb - func, - const void - *data); - EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler * - win32_handler); - - EAPI Ecore_Pipe *ecore_pipe_add(Ecore_Pipe_Cb handler, - const void *data); - EAPI void *ecore_pipe_del(Ecore_Pipe * p); - EAPI Eina_Bool ecore_pipe_write(Ecore_Pipe * p, const void *buffer, - unsigned int nbytes); - EAPI void ecore_pipe_write_close(Ecore_Pipe * p); - EAPI void ecore_pipe_read_close(Ecore_Pipe * p); - - - - EAPI Ecore_Thread *ecore_thread_run(Ecore_Cb, - Ecore_Cb, - Ecore_Cb, const void *data); - EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Heavy_Cb, - Ecore_Thread_Notify_Cb, - Ecore_Cb, - Ecore_Cb, - const void *data, - Eina_Bool - try_no_queue); - EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread * thread); - EAPI Eina_Bool ecore_thread_check(Ecore_Thread * thread); - EAPI Eina_Bool ecore_thread_feedback(Ecore_Thread * thread, - const void *msg_data); - EAPI int ecore_thread_active_get(void); - EAPI int ecore_thread_pending_get(void); - EAPI int ecore_thread_pending_feedback_get(void); - EAPI int ecore_thread_pending_total_get(void); - EAPI int ecore_thread_max_get(void); - EAPI void ecore_thread_max_set(int num); - EAPI void ecore_thread_max_reset(void); - EAPI int ecore_thread_available_get(void); - - EAPI Eina_Bool ecore_thread_local_data_add(Ecore_Thread * thread, - const char *key, - void *value, - Eina_Free_Cb cb, - Eina_Bool direct); - EAPI void *ecore_thread_local_data_set(Ecore_Thread * thread, - const char *key, - void *value, - Eina_Free_Cb cb); - EAPI void *ecore_thread_local_data_find(Ecore_Thread * thread, - const char *key); - EAPI Eina_Bool ecore_thread_local_data_del(Ecore_Thread * thread, - const char *key); - - EAPI Eina_Bool ecore_thread_global_data_add(const char *key, - void *value, - Eina_Free_Cb cb, - Eina_Bool direct); - EAPI void *ecore_thread_global_data_set(const char *key, - void *value, - Eina_Free_Cb cb); - EAPI void *ecore_thread_global_data_find(const char *key); - EAPI Eina_Bool ecore_thread_global_data_del(const char *key); - EAPI void *ecore_thread_global_data_wait(const char *key, - double seconds); - - - - - EAPI double ecore_time_get(void); - EAPI double ecore_time_unix_get(void); - EAPI double ecore_loop_time_get(void); - - EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, - const void *data); - EAPI Ecore_Timer *ecore_timer_loop_add(double in, - Ecore_Task_Cb func, - const void *data); - EAPI void *ecore_timer_del(Ecore_Timer * timer); - EAPI void ecore_timer_interval_set(Ecore_Timer * timer, double in); - EAPI double ecore_timer_interval_get(Ecore_Timer * timer); - EAPI void ecore_timer_freeze(Ecore_Timer * timer); - EAPI void ecore_timer_thaw(Ecore_Timer * timer); - EAPI void ecore_timer_delay(Ecore_Timer * timer, double add); - EAPI double ecore_timer_pending_get(Ecore_Timer * timer); - - EAPI double ecore_timer_precision_get(void); - EAPI void ecore_timer_precision_set(double precision); - - EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func, - const void *data); - EAPI void *ecore_animator_del(Ecore_Animator * animator); - EAPI void ecore_animator_freeze(Ecore_Animator * animator); - EAPI void ecore_animator_thaw(Ecore_Animator * animator); - EAPI void ecore_animator_frametime_set(double frametime); - EAPI double ecore_animator_frametime_get(void); - - EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, - double poll_time); - EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type); - EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller * - poller, - int interval); - EAPI int ecore_poller_poller_interval_get(Ecore_Poller * poller); - EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, - int interval, - Ecore_Task_Cb func, - const void *data); - EAPI void *ecore_poller_del(Ecore_Poller * poller); - - EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data); - EAPI void *ecore_job_del(Ecore_Job * job); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/tests/suite/ecore/src/lib/Ecore_Getopt.h b/tests/suite/ecore/src/lib/Ecore_Getopt.h deleted file mode 100644 index d3dc5688a3..0000000000 --- a/tests/suite/ecore/src/lib/Ecore_Getopt.h +++ /dev/null @@ -1,436 +0,0 @@ -#ifndef _ECORE_GETOPT_H -#define _ECORE_GETOPT_H - -#include <stdio.h> -#include <Eina.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_Getopt.h - * @brief Contains powerful getopt replacement. - * - * This replacement handles both short (-X) or long options (--ABC) - * options, with various actions supported, like storing one value and - * already converting to required type, counting number of - * occurrences, setting true or false values, show help, license, - * copyright and even support user-defined callbacks. - * - * It is provided a set of C Pre Processor macros so definition is - * straightforward. - * - * Values will be stored elsewhere indicated by an array of pointers - * to values, it is given in separate to parser description so you can - * use multiple values with the same parser. - */ - - -#ifdef __cplusplus -extern "C" { -#endif - - typedef enum { - ECORE_GETOPT_ACTION_STORE, - ECORE_GETOPT_ACTION_STORE_CONST, - ECORE_GETOPT_ACTION_STORE_TRUE, - ECORE_GETOPT_ACTION_STORE_FALSE, - ECORE_GETOPT_ACTION_CHOICE, - ECORE_GETOPT_ACTION_APPEND, - ECORE_GETOPT_ACTION_COUNT, - ECORE_GETOPT_ACTION_CALLBACK, - ECORE_GETOPT_ACTION_HELP, - ECORE_GETOPT_ACTION_VERSION, - ECORE_GETOPT_ACTION_COPYRIGHT, - ECORE_GETOPT_ACTION_LICENSE - } Ecore_Getopt_Action; - - typedef enum { - ECORE_GETOPT_TYPE_STR, - ECORE_GETOPT_TYPE_BOOL, - ECORE_GETOPT_TYPE_SHORT, - ECORE_GETOPT_TYPE_INT, - ECORE_GETOPT_TYPE_LONG, - ECORE_GETOPT_TYPE_USHORT, - ECORE_GETOPT_TYPE_UINT, - ECORE_GETOPT_TYPE_ULONG, - ECORE_GETOPT_TYPE_DOUBLE - } Ecore_Getopt_Type; - - typedef enum { - ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO = 0, - ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES = 1, - ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL = 3 - } Ecore_Getopt_Desc_Arg_Requirement; - - typedef union _Ecore_Getopt_Value Ecore_Getopt_Value; - - typedef struct _Ecore_Getopt_Desc_Store Ecore_Getopt_Desc_Store; - typedef struct _Ecore_Getopt_Desc_Callback - Ecore_Getopt_Desc_Callback; - typedef struct _Ecore_Getopt_Desc Ecore_Getopt_Desc; - typedef struct _Ecore_Getopt Ecore_Getopt; - - union _Ecore_Getopt_Value { - char **strp; - unsigned char *boolp; - short *shortp; - int *intp; - long *longp; - unsigned short *ushortp; - unsigned int *uintp; - unsigned long *ulongp; - double *doublep; - Eina_List **listp; - void **ptrp; - }; - - struct _Ecore_Getopt_Desc_Store { - Ecore_Getopt_Type type;/**< type of data being handled */ - Ecore_Getopt_Desc_Arg_Requirement arg_req; - union { - const char *strv; - unsigned char boolv; - short shortv; - int intv; - long longv; - unsigned short ushortv; - unsigned int uintv; - unsigned long ulongv; - double doublev; - } def; - }; - - struct _Ecore_Getopt_Desc_Callback { - unsigned char (*func) (const Ecore_Getopt * parser, - const Ecore_Getopt_Desc * desc, - const char *str, void *data, - Ecore_Getopt_Value * storage); - const void *data; - Ecore_Getopt_Desc_Arg_Requirement arg_req; - const char *def; - }; - - struct _Ecore_Getopt_Desc { - char shortname; - /**< used with a single dash */ - const char *longname; - /**< used with double dashes */ - const char *help; - /**< used by --help/ecore_getopt_help() */ - const char *metavar; - /**< used by ecore_getopt_help() with nargs > 0 */ - - Ecore_Getopt_Action action; - /**< define how to handle it */ - union { - const Ecore_Getopt_Desc_Store store; - const void *store_const; - const char *const *choices; /* NULL terminated. */ - const Ecore_Getopt_Type append_type; - const Ecore_Getopt_Desc_Callback callback; - const void *dummy; - } action_param; - }; - - struct _Ecore_Getopt { - const char *prog; - /**< to be used when ecore_app_args_get() fails */ - const char *usage; - /**< usage example, %prog is replaced */ - const char *version; - /**< if exists, --version will work */ - const char *copyright; - /**< if exists, --copyright will work */ - const char *license; - /**< if exists, --license will work */ - const char *description; - /**< long description, possible multiline */ - unsigned char strict:1; - /**< fail on errors */ - const Ecore_Getopt_Desc descs[]; /* NULL terminated. */ - }; - -#define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \ - {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE, \ - {.store = {type, arg_requirement, default_value}}} - -#define ECORE_GETOPT_STORE(shortname, longname, help, type) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \ - ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {}) - -#define ECORE_GETOPT_STORE_STR(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_STR) -#define ECORE_GETOPT_STORE_BOOL(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_BOOL) -#define ECORE_GETOPT_STORE_SHORT(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_SHORT) -#define ECORE_GETOPT_STORE_INT(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_INT) -#define ECORE_GETOPT_STORE_LONG(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_LONG) -#define ECORE_GETOPT_STORE_USHORT(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_USHORT) -#define ECORE_GETOPT_STORE_UINT(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_UINT) -#define ECORE_GETOPT_STORE_ULONG(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_ULONG) -#define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help) \ - ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_DOUBLE) - - -#define ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, type) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, \ - ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {}) - -#define ECORE_GETOPT_STORE_METAVAR_STR(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_STR) -#define ECORE_GETOPT_STORE_METAVAR_BOOL(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_BOOL) -#define ECORE_GETOPT_STORE_METAVAR_SHORT(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_SHORT) -#define ECORE_GETOPT_STORE_METAVAR_INT(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_INT) -#define ECORE_GETOPT_STORE_METAVAR_LONG(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_LONG) -#define ECORE_GETOPT_STORE_METAVAR_USHORT(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_USHORT) -#define ECORE_GETOPT_STORE_METAVAR_UINT(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_UINT) -#define ECORE_GETOPT_STORE_METAVAR_ULONG(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_ULONG) -#define ECORE_GETOPT_STORE_METAVAR_DOUBLE(shortname, longname, help, metavar) \ - ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_DOUBLE) - - -#define ECORE_GETOPT_STORE_DEF(shortname, longname, help, type, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \ - ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL, \ - default_value) - -#define ECORE_GETOPT_STORE_DEF_STR(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_STR, \ - {.strv = default_value}) -#define ECORE_GETOPT_STORE_DEF_BOOL(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_BOOL, \ - {.boolv = default_value}) -#define ECORE_GETOPT_STORE_DEF_SHORT(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_SHORT, \ - {.shortv = default_value}) -#define ECORE_GETOPT_STORE_DEF_INT(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_INT, \ - {.intv = default_value}) -#define ECORE_GETOPT_STORE_DEF_LONG(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_LONG, \ - {.longv = default_value}) -#define ECORE_GETOPT_STORE_DEF_USHORT(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_USHORT, \ - {.ushortv = default_value}) -#define ECORE_GETOPT_STORE_DEF_UINT(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_UINT, \ - {.uintv = default_value}) -#define ECORE_GETOPT_STORE_DEF_ULONG(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_ULONG, \ - {.ulongv = default_value}) -#define ECORE_GETOPT_STORE_DEF_DOUBLE(shortname, longname, help, default_value) \ - ECORE_GETOPT_STORE_DEF(shortname, longname, help, \ - ECORE_GETOPT_TYPE_DOUBLE, \ - {.doublev = default_value}) - -#define ECORE_GETOPT_STORE_FULL_STR(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_STR, \ - arg_requirement, \ - {.strv = default_value}) -#define ECORE_GETOPT_STORE_FULL_BOOL(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_BOOL, \ - arg_requirement, \ - {.boolv = default_value}) -#define ECORE_GETOPT_STORE_FULL_SHORT(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_SHORT, \ - arg_requirement, \ - {.shortv = default_value}) -#define ECORE_GETOPT_STORE_FULL_INT(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_INT, \ - arg_requirement, \ - {.intv = default_value}) -#define ECORE_GETOPT_STORE_FULL_LONG(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_LONG, \ - arg_requirement, \ - {.longv = default_value}) -#define ECORE_GETOPT_STORE_FULL_USHORT(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_USHORT, \ - arg_requirement, \ - {.ushortv = default_value}) -#define ECORE_GETOPT_STORE_FULL_UINT(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_UINT, \ - arg_requirement, \ - {.uintv = default_value}) -#define ECORE_GETOPT_STORE_FULL_ULONG(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_ULONG, \ - arg_requirement, \ - {.ulongv = default_value}) -#define ECORE_GETOPT_STORE_FULL_DOUBLE(shortname, longname, help, metavar, arg_requirement, default_value) \ - ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \ - ECORE_GETOPT_TYPE_DOUBLE, \ - arg_requirement, \ - {.doublev = default_value}) - -#define ECORE_GETOPT_STORE_CONST(shortname, longname, help, value) \ - {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_CONST, \ - {.store_const = value}} -#define ECORE_GETOPT_STORE_TRUE(shortname, longname, help) \ - {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_TRUE, \ - {.dummy = NULL}} -#define ECORE_GETOPT_STORE_FALSE(shortname, longname, help) \ - {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_FALSE, \ - {.dummy = NULL}} - -#define ECORE_GETOPT_CHOICE(shortname, longname, help, choices_array) \ - {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_CHOICE, \ - {.choices = choices_array}} -#define ECORE_GETOPT_CHOICE_METAVAR(shortname, longname, help, metavar, choices_array) \ - {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CHOICE, \ - {.choices = choices_array}} - - -#define ECORE_GETOPT_APPEND(shortname, longname, help, sub_type) \ - {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_APPEND, \ - {.append_type = sub_type}} -#define ECORE_GETOPT_APPEND_METAVAR(shortname, longname, help, metavar, type) \ - {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_APPEND, \ - {.append_type = type}} - -#define ECORE_GETOPT_COUNT(shortname, longname, help) \ - {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_COUNT, \ - {.dummy = NULL}} - -#define ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, callback_func, callback_data, argument_requirement, default_value) \ - {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CALLBACK, \ - {.callback = {callback_func, callback_data, \ - argument_requirement, default_value}}} -#define ECORE_GETOPT_CALLBACK_NOARGS(shortname, longname, help, callback_func, callback_data) \ - ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, NULL, \ - callback_func, callback_data, \ - ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO, \ - NULL) -#define ECORE_GETOPT_CALLBACK_ARGS(shortname, longname, help, metavar, callback_func, callback_data) \ - ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, \ - callback_func, callback_data, \ - ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, \ - NULL) - -#define ECORE_GETOPT_HELP(shortname, longname) \ - {shortname, longname, "show this message.", NULL, \ - ECORE_GETOPT_ACTION_HELP, \ - {.dummy = NULL}} - -#define ECORE_GETOPT_VERSION(shortname, longname) \ - {shortname, longname, "show program version.", NULL, \ - ECORE_GETOPT_ACTION_VERSION, \ - {.dummy = NULL}} - -#define ECORE_GETOPT_COPYRIGHT(shortname, longname) \ - {shortname, longname, "show copyright.", NULL, \ - ECORE_GETOPT_ACTION_COPYRIGHT, \ - {.dummy = NULL}} - -#define ECORE_GETOPT_LICENSE(shortname, longname) \ - {shortname, longname, "show license.", NULL, \ - ECORE_GETOPT_ACTION_LICENSE, \ - {.dummy = NULL}} - -#define ECORE_GETOPT_SENTINEL {0, NULL, NULL, NULL, 0, {.dummy = NULL}} - -#define ECORE_GETOPT_VALUE_STR(val) {.strp = &(val)} -#define ECORE_GETOPT_VALUE_BOOL(val) {.boolp = &(val)} -#define ECORE_GETOPT_VALUE_SHORT(val) {.shortp = &(val)} -#define ECORE_GETOPT_VALUE_INT(val) {.intp = &(val)} -#define ECORE_GETOPT_VALUE_LONG(val) {.longp = &(val)} -#define ECORE_GETOPT_VALUE_USHORT(val) {.ushortp = &(val)} -#define ECORE_GETOPT_VALUE_UINT(val) {.uintp = &(val)} -#define ECORE_GETOPT_VALUE_ULONG(val) {.ulongp = &(val)} -#define ECORE_GETOPT_VALUE_DOUBLE(val) {.doublep = &(val)} -#define ECORE_GETOPT_VALUE_PTR(val) {.ptrp = &(val)} -#define ECORE_GETOPT_VALUE_PTR_CAST(val) {.ptrp = (void **)&(val)} -#define ECORE_GETOPT_VALUE_LIST(val) {.listp = &(val)} -#define ECORE_GETOPT_VALUE_NONE {.ptrp = NULL} - - EAPI void ecore_getopt_help(FILE * fp, const Ecore_Getopt * info); - - EAPI unsigned char ecore_getopt_parser_has_duplicates(const - Ecore_Getopt - * parser); - EAPI int ecore_getopt_parse(const Ecore_Getopt * parser, - Ecore_Getopt_Value * values, int argc, - char **argv); - - EAPI Eina_List *ecore_getopt_list_free(Eina_List * list); - - /* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */ - EAPI unsigned char ecore_getopt_callback_geometry_parse(const - Ecore_Getopt - * parser, - const - Ecore_Getopt_Desc - * desc, - const char - *str, - void *data, - Ecore_Getopt_Value - * storage); - EAPI unsigned char ecore_getopt_callback_size_parse(const - Ecore_Getopt * - parser, - const - Ecore_Getopt_Desc - * desc, - const char - *str, - void *data, - Ecore_Getopt_Value - * storage); - - -#ifdef __cplusplus -} -#endif -#endif /* _ECORE_GETOPT_H */ diff --git a/tests/suite/ecore/src/lib/ecore.c b/tests/suite/ecore/src/lib/ecore.c deleted file mode 100644 index 09842d1807..0000000000 --- a/tests/suite/ecore/src/lib/ecore.c +++ /dev/null @@ -1,406 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> - -#ifndef _MSC_VER -#include <unistd.h> -#endif - -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif - -#ifdef HAVE_LANGINFO_H -#include <langinfo.h> -#endif - -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif -#include <Eina.h> - -#include "Ecore.h" -#include "ecore_private.h" - -#if HAVE_MALLINFO -#include <malloc.h> - -static Ecore_Version _version = { VERS_MAJ, VERS_MIN, VERS_MIC, VERS_REV }; - -EAPI Ecore_Version *ecore_version = &_version; - -#define KEEP_MAX(Global, Local) \ - if (Global < (Local)) \ - Global = Local; - -static Eina_Bool _ecore_memory_statistic(void *data); -static int _ecore_memory_max_total = 0; -static int _ecore_memory_max_free = 0; -static pid_t _ecore_memory_pid = 0; -#endif - -static const char *_ecore_magic_string_get(Ecore_Magic m); -static int _ecore_init_count = 0; -int _ecore_log_dom = -1; -int _ecore_fps_debug = 0; - -/** OpenBSD does not define CODESET - * FIXME ?? - */ - -#ifndef CODESET -#define CODESET "INVALID" -#endif - -/** - * Set up connections, signal handlers, sockets etc. - * @return 1 or greater on success, 0 otherwise - * - * This function sets up all singal handlers and the basic event loop. If it - * succeeds, 1 will be returned, otherwise 0 will be returned. - * - * @code - * #include <Ecore.h> - * - * int main(int argc, char **argv) - * { - * if (!ecore_init()) - * { - * printf("ERROR: Cannot init Ecore!\n"); - * return -1; - * } - * ecore_main_loop_begin(); - * ecore_shutdown(); - * } - * @endcode - */ -EAPI int ecore_init(void) -{ - if (++_ecore_init_count != 1) - return _ecore_init_count; - -#ifdef HAVE_LOCALE_H - setlocale(LC_CTYPE, ""); -#endif - /* - if (strcmp(nl_langinfo(CODESET), "UTF-8")) - { - WRN("Not a utf8 locale!"); - } - */ -#ifdef HAVE_EVIL - if (!evil_init()) - return --_ecore_init_count; -#endif - if (!eina_init()) - goto shutdown_evil; - _ecore_log_dom = - eina_log_domain_register("Ecore", ECORE_DEFAULT_LOG_COLOR); - if (_ecore_log_dom < 0) { - EINA_LOG_ERR("Ecore was unable to create a log domain."); - goto shutdown_log_dom; - } - if (getenv("ECORE_FPS_DEBUG")) - _ecore_fps_debug = 1; - if (_ecore_fps_debug) - _ecore_fps_debug_init(); - _ecore_main_loop_init(); - _ecore_signal_init(); - _ecore_exe_init(); - _ecore_thread_init(); - _ecore_glib_init(); - _ecore_job_init(); - _ecore_time_init(); - -#if HAVE_MALLINFO - if (getenv("ECORE_MEM_STAT")) { - _ecore_memory_pid = getpid(); - ecore_animator_add(_ecore_memory_statistic, NULL); - } -#endif - -#if defined(GLIB_INTEGRATION_ALWAYS) - if (_ecore_glib_always_integrate) - ecore_main_loop_glib_integrate(); -#endif - - return _ecore_init_count; - - shutdown_log_dom: - eina_shutdown(); - shutdown_evil: -#ifdef HAVE_EVIL - evil_shutdown(); -#endif - return --_ecore_init_count; -} - -/** - * Shut down connections, signal handlers sockets etc. - * - * This function shuts down all things set up in ecore_init() and cleans up all - * event queues, handlers, filters, timers, idlers, idle enterers/exiters - * etc. set up after ecore_init() was called. - * - * Do not call this function from any callback that may be called from the main - * loop, as the main loop will then fall over and not function properly. - */ -EAPI int ecore_shutdown(void) -{ - if (--_ecore_init_count != 0) - return _ecore_init_count; - - if (_ecore_fps_debug) - _ecore_fps_debug_shutdown(); - _ecore_poller_shutdown(); - _ecore_animator_shutdown(); - _ecore_glib_shutdown(); - _ecore_job_shutdown(); - _ecore_thread_shutdown(); - _ecore_exe_shutdown(); - _ecore_idle_enterer_shutdown(); - _ecore_idle_exiter_shutdown(); - _ecore_idler_shutdown(); - _ecore_timer_shutdown(); - _ecore_event_shutdown(); - _ecore_main_shutdown(); - _ecore_signal_shutdown(); - _ecore_main_loop_shutdown(); - -#if HAVE_MALLINFO - if (getenv("ECORE_MEM_STAT")) { - _ecore_memory_statistic(NULL); - - ERR("[%i] Memory MAX total: %i, free: %i", - _ecore_memory_pid, - _ecore_memory_max_total, _ecore_memory_max_free); - } -#endif - - eina_log_domain_unregister(_ecore_log_dom); - _ecore_log_dom = -1; - eina_shutdown(); -#ifdef HAVE_EVIL - evil_shutdown(); -#endif - - return _ecore_init_count; -} - -EAPI void ecore_print_warning(const char *function, const char *sparam) -{ - WRN("***** 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(); -} - -EAPI void -_ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, - const char *fname) -{ - ERR("\n" - "*** ECORE ERROR: Ecore Magic Check Failed!!!\n" - "*** IN FUNCTION: %s()", fname); - if (!d) - ERR(" Input handle pointer is NULL!"); - else if (m == ECORE_MAGIC_NONE) - ERR(" Input handle has already been freed!"); - else if (m != req_m) - ERR(" Input handle is wrong type\n" - " Expected: %08x - %s\n" - " Supplied: %08x - %s", - (unsigned int) req_m, _ecore_magic_string_get(req_m), - (unsigned int) m, _ecore_magic_string_get(m)); - ERR("*** NAUGHTY PROGRAMMER!!!\n" - "*** SPANK SPANK SPANK!!!\n" - "*** Now go fix your code. Tut tut tut!"); - if (getenv("ECORE_ERROR_ABORT")) - abort(); -} - -static const char *_ecore_magic_string_get(Ecore_Magic m) -{ - switch (m) { - case ECORE_MAGIC_NONE: - return "None (Freed Object)"; - break; - case ECORE_MAGIC_EXE: - return "Ecore_Exe (Executable)"; - break; - case ECORE_MAGIC_TIMER: - return "Ecore_Timer (Timer)"; - break; - case ECORE_MAGIC_IDLER: - return "Ecore_Idler (Idler)"; - break; - case ECORE_MAGIC_IDLE_ENTERER: - return "Ecore_Idle_Enterer (Idler Enterer)"; - break; - case ECORE_MAGIC_IDLE_EXITER: - return "Ecore_Idle_Exiter (Idler Exiter)"; - break; - case ECORE_MAGIC_FD_HANDLER: - return "Ecore_Fd_Handler (Fd Handler)"; - break; - case ECORE_MAGIC_WIN32_HANDLER: - return "Ecore_Win32_Handler (Win32 Handler)"; - break; - case ECORE_MAGIC_EVENT_HANDLER: - return "Ecore_Event_Handler (Event Handler)"; - break; - case ECORE_MAGIC_EVENT: - return "Ecore_Event (Event)"; - break; - default: - return "<UNKNOWN>"; - }; -} - -/* fps debug calls - for debugging how much time your app actually spends */ -/* "running" (and the inverse being time spent running)... this does not */ -/* account for other apps and multitasking... */ - -static int _ecore_fps_debug_init_count = 0; -static int _ecore_fps_debug_fd = -1; -unsigned int *_ecore_fps_runtime_mmap = NULL; - -void _ecore_fps_debug_init(void) -{ - char buf[4096]; - const char *tmp; - int pid; - - _ecore_fps_debug_init_count++; - if (_ecore_fps_debug_init_count > 1) - return; - -#ifndef HAVE_EVIL - tmp = "/tmp"; -#else - tmp = (char *) evil_tmpdir_get(); -#endif /* HAVE_EVIL */ - pid = (int) getpid(); - snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid); - _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644); - if (_ecore_fps_debug_fd < 0) { - unlink(buf); - _ecore_fps_debug_fd = - open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644); - } - if (_ecore_fps_debug_fd >= 0) { - unsigned int zero = 0; - char *buf = (char *) &zero; - ssize_t todo = sizeof(unsigned int); - - while (todo > 0) { - ssize_t r = write(_ecore_fps_debug_fd, buf, todo); - if (r > 0) { - todo -= r; - buf += r; - } else if ((r < 0) && (errno == EINTR)) - continue; - else { - ERR("could not write to file '%s' fd %d: %s", tmp, _ecore_fps_debug_fd, strerror(errno)); - close(_ecore_fps_debug_fd); - _ecore_fps_debug_fd = -1; - return; - } - } - _ecore_fps_runtime_mmap = mmap(NULL, sizeof(unsigned int), - PROT_READ | PROT_WRITE, - MAP_SHARED, - _ecore_fps_debug_fd, 0); - if (_ecore_fps_runtime_mmap == MAP_FAILED) - _ecore_fps_runtime_mmap = NULL; - } -} - -void _ecore_fps_debug_shutdown(void) -{ - _ecore_fps_debug_init_count--; - if (_ecore_fps_debug_init_count > 0) - return; - if (_ecore_fps_debug_fd >= 0) { - char buf[4096]; - const char *tmp; - int pid; - -#ifndef HAVE_EVIL - tmp = "/tmp"; -#else - tmp = (char *) evil_tmpdir_get(); -#endif /* HAVE_EVIL */ - pid = (int) getpid(); - snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, - pid); - unlink(buf); - if (_ecore_fps_runtime_mmap) { - munmap(_ecore_fps_runtime_mmap, sizeof(int)); - _ecore_fps_runtime_mmap = NULL; - } - close(_ecore_fps_debug_fd); - _ecore_fps_debug_fd = -1; - } -} - -void _ecore_fps_debug_runtime_add(double t) -{ - if ((_ecore_fps_debug_fd >= 0) && (_ecore_fps_runtime_mmap)) { - unsigned int tm; - - tm = (unsigned int) (t * 1000000.0); - /* i know its not 100% theoretically guaranteed, but i'd say a write */ - /* of an int could be considered atomic for all practical purposes */ - /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */ - /* this can run for about 4294 seconds becore looping. if you are */ - /* doing performance testing in one run for over an hour... well */ - /* time to restart or handle a loop condition :) */ - *(_ecore_fps_runtime_mmap) += tm; - } -} - -#if HAVE_MALLINFO -static Eina_Bool _ecore_memory_statistic(__UNUSED__ void *data) -{ - struct mallinfo mi; - static int uordblks = 0; - static int fordblks = 0; - Eina_Bool changed = EINA_FALSE; - - mi = mallinfo(); - -#define HAS_CHANGED(Global, Local) \ - if (Global != Local) \ - { \ - Global = Local; \ - changed = EINA_TRUE; \ - } - - HAS_CHANGED(uordblks, mi.uordblks); - HAS_CHANGED(fordblks, mi.fordblks); - - if (changed) - ERR("[%i] Memory total: %i, free: %i", - _ecore_memory_pid, mi.uordblks, mi.fordblks); - - KEEP_MAX(_ecore_memory_max_total, mi.uordblks); - KEEP_MAX(_ecore_memory_max_free, mi.fordblks); - - return ECORE_CALLBACK_RENEW; -} -#endif diff --git a/tests/suite/ecore/src/lib/ecore_anim.c b/tests/suite/ecore/src/lib/ecore_anim.c deleted file mode 100644 index ff37e393e9..0000000000 --- a/tests/suite/ecore/src/lib/ecore_anim.c +++ /dev/null @@ -1,235 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <math.h> - -#include "Ecore.h" -#include "ecore_private.h" - - -struct _Ecore_Animator { - EINA_INLIST; - ECORE_MAGIC; - - Ecore_Task_Cb func; - void *data; - - Eina_Bool delete_me:1; - Eina_Bool suspended:1; -}; - - -static Eina_Bool _ecore_animator(void *data); - -static Ecore_Timer *timer = NULL; -static int animators_delete_me = 0; -static Ecore_Animator *animators = NULL; -static double animators_frametime = 1.0 / 30.0; - -/** - * Add a animator to tick off at every animaton tick during main loop execution. - * @param func The function to call when it ticks off - * @param data The data to pass to the function - * @return A handle to the new animator - * @ingroup Ecore_Animator_Group - * - * This function adds a animator and returns its handle on success and NULL on - * failure. The function @p func will be called every N seconds where N is the - * frametime interval set by ecore_animator_frametime_set(). The function will - * be passed the @p data pointer as its parameter. - * - * When the animator @p func is called, it must return a value of either 1 or 0. - * If it returns 1 (or ECORE_CALLBACK_RENEW), it will be called again at the - * next tick, or if it returns 0 (or ECORE_CALLBACK_CANCEL) it will be deleted - * automatically making any references/handles for it invalid. - */ -EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Animator *animator; - - if (!func) - return NULL; - animator = calloc(1, sizeof(Ecore_Animator)); - if (!animator) - return NULL; - ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR); - animator->func = func; - animator->data = (void *) data; - animators = - (Ecore_Animator *) - eina_inlist_append(EINA_INLIST_GET(animators), - EINA_INLIST_GET(animator)); - if (!timer) { - double t_loop = ecore_loop_time_get(); - double sync_0 = 0.0; - double d = -fmod(t_loop - sync_0, animators_frametime); - - timer = - ecore_timer_loop_add(animators_frametime, - _ecore_animator, NULL); - ecore_timer_delay(timer, d); - } - return animator; -} - -/** - * Delete the specified animator from the animator list. - * @param animator The animator to delete - * @return The data pointer set for the animator - * @ingroup Ecore_Animator_Group - * - * Delete the specified @p aqnimator from the set of animators that are executed - * during main loop execution. This function returns the data parameter that - * was being passed to the callback on success, or NULL on failure. After this - * call returns the specified animator object @p animator is invalid and should not - * be used again. It will not get called again after deletion. - */ -EAPI void *ecore_animator_del(Ecore_Animator * animator) -{ - if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR)) { - ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR, - "ecore_animator_del"); - return NULL; - } - if (animator->delete_me) - return animator->data; - animator->delete_me = EINA_TRUE; - animators_delete_me++; - return animator->data; -} - -/** - * Set the animator call interval in seconds. - * @param frametime The time in seconds in between animator ticks. - * - * This function sets the time interval (in seconds) between animator ticks. - */ -EAPI void ecore_animator_frametime_set(double frametime) -{ - if (frametime < 0.0) - frametime = 0.0; - if (animators_frametime == frametime) - return; - animators_frametime = frametime; - if (timer) { - ecore_timer_del(timer); - timer = NULL; - } - if (animators) - timer = - ecore_timer_add(animators_frametime, _ecore_animator, - NULL); -} - -/** - * Get the animator call interval in seconds. - * @return The time in second in between animator ticks. - * - * this function retrieves the time between animator ticks, in seconds. - */ -EAPI double ecore_animator_frametime_get(void) -{ - return animators_frametime; -} - -/** - * Suspend the specified animator. - * @param animator The animator to delete - * @ingroup Ecore_Animator_Group - * - * The specified @p animator will be temporarly removed from the set of animators - * that are executed during main loop execution. - */ -EAPI void ecore_animator_freeze(Ecore_Animator * animator) -{ - if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR)) { - ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR, - "ecore_animator_del"); - return; - } - if (animator->delete_me) - return; - animator->suspended = EINA_TRUE; -} - -/** - * Restore execution of the specified animator. - * @param animator The animator to delete - * @ingroup Ecore_Animator_Group - * - * The specified @p animator will be put back in the set of animators - * that are executed during main loop execution. - */ -EAPI void ecore_animator_thaw(Ecore_Animator * animator) -{ - if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR)) { - ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR, - "ecore_animator_del"); - return; - } - if (animator->delete_me) - return; - animator->suspended = EINA_FALSE; -} - -void _ecore_animator_shutdown(void) -{ - if (timer) { - ecore_timer_del(timer); - timer = NULL; - } - while (animators) { - Ecore_Animator *animator; - - animator = animators; - animators = - (Ecore_Animator *) - eina_inlist_remove(EINA_INLIST_GET(animators), - EINA_INLIST_GET(animators)); - ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE); - free(animator); - } -} - -static Eina_Bool _ecore_animator(void *data __UNUSED__) -{ - Ecore_Animator *animator; - - EINA_INLIST_FOREACH(animators, animator) { - if (!animator->delete_me && !animator->suspended) { - if (!animator->func(animator->data)) { - animator->delete_me = EINA_TRUE; - animators_delete_me++; - } - } - } - if (animators_delete_me) { - Ecore_Animator *l; - for (l = animators; l;) { - animator = l; - l = (Ecore_Animator *) EINA_INLIST_GET(l)->next; - if (animator->delete_me) { - animators = - (Ecore_Animator *) - eina_inlist_remove(EINA_INLIST_GET - (animators), - EINA_INLIST_GET - (animator)); - ECORE_MAGIC_SET(animator, - ECORE_MAGIC_NONE); - free(animator); - animators_delete_me--; - if (animators_delete_me == 0) - break; - } - } - } - if (!animators) { - timer = NULL; - return ECORE_CALLBACK_CANCEL; - } - return ECORE_CALLBACK_RENEW; -} diff --git a/tests/suite/ecore/src/lib/ecore_app.c b/tests/suite/ecore/src/lib/ecore_app.c deleted file mode 100644 index b83e5b2958..0000000000 --- a/tests/suite/ecore/src/lib/ecore_app.c +++ /dev/null @@ -1,79 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#ifndef _MSC_VER -#include <unistd.h> -#else -#include <process.h> -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -static int app_argc = 0; -static char **app_argv = NULL; - -/** - * Set up the programs command-line arguments. - * @param argc The same as passed as argc to the programs main() function - * @param argv The same as passed as argv to the programs main() function - * - * A call to this function will store the programs command-line arguments - * for later use by ecore_app_restart() or ecore_app_args_get(). - */ -EAPI void ecore_app_args_set(int argc, const char **argv) -{ - if ((argc < 1) || (!argv)) - return; - app_argc = argc; - app_argv = (char **) argv; -} - -/** - * Return the programs stored command-line arguments. - * @param argc A pointer to the return value to hold argc - * @param argv A pointer to the return value to hold argv - * - * When called, this funciton returns the arguments for the program stored by - * ecore_app_args_set(). The integer pointed to by @p argc will be filled, if - * the pointer is not NULL, and the string array pointer @p argv will be filled - * also if the pointer is not NULL. The values they are filled with will be the - * same set by ecore_app_args_set(). - */ -EAPI void ecore_app_args_get(int *argc, char ***argv) -{ - if (argc) - *argc = app_argc; - if (argv) - *argv = app_argv; -} - -/** - * Restart the program executable with the command-line arguments stored. - * - * This function will restart & re-execute this program in place of itself - * using the command-line arguments stored by ecore_app_args_set(). This is - * an easy way for a program to restart itself for cleanup purposes, - * configuration reasons or in the event of a crash. - */ -EAPI void ecore_app_restart(void) -{ - char *args[4096]; - int i; - - if ((app_argc < 1) || (!app_argv)) - return; - if (app_argc >= 4096) - return; - for (i = 0; i < app_argc; i++) - args[i] = app_argv[i]; - args[i] = NULL; - execvp(app_argv[0], args); -} diff --git a/tests/suite/ecore/src/lib/ecore_events.c b/tests/suite/ecore/src/lib/ecore_events.c deleted file mode 100644 index ebe22219d3..0000000000 --- a/tests/suite/ecore/src/lib/ecore_events.c +++ /dev/null @@ -1,696 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include "Ecore.h" -#include "ecore_private.h" - -static int inpurge = 0; - -struct _Ecore_Event_Handler { - EINA_INLIST; - ECORE_MAGIC; - int type; - Ecore_Event_Handler_Cb func; - void *data; - int references; - Eina_Bool delete_me:1; -}; - -struct _Ecore_Event_Filter { - EINA_INLIST; - ECORE_MAGIC; - Ecore_Data_Cb func_start; - Ecore_Filter_Cb func_filter; - Ecore_End_Cb func_end; - void *loop_data; - void *data; - int references; - Eina_Bool delete_me:1; -}; - -struct _Ecore_Event { - EINA_INLIST; - ECORE_MAGIC; - int type; - void *event; - Ecore_End_Cb func_free; - void *data; - int references; - Eina_Bool delete_me:1; -}; - - -static int events_num = 0; -static Ecore_Event *events = NULL; -static Ecore_Event *event_current = NULL; -static Ecore_Event *purge_events = NULL; - -static Ecore_Event_Handler **event_handlers = NULL; -static Ecore_Event_Handler *event_handler_current = NULL; -static int event_handlers_num = 0; -static int event_handlers_alloc_num = 0; -static Eina_List *event_handlers_delete_list = NULL; - -static Ecore_Event_Filter *event_filters = NULL; -static Ecore_Event_Filter *event_filter_current = NULL; -static Ecore_Event *event_filter_event_current = NULL; -static int event_filters_delete_me = 0; -static int event_id_max = ECORE_EVENT_COUNT; -static int ecore_raw_event_type = ECORE_EVENT_NONE; -static void *ecore_raw_event_event = NULL; - - -static void _ecore_event_purge_deleted(void); -static void *_ecore_event_del(Ecore_Event * event); - - -/** - * Add an event handler. - * @param type The type of the event this handler will get called for - * @param func The function to call when the event is found in the queue - * @param data A data pointer to pass to the called function @p func - * @return A new Event handler, or NULL on failure - * - * Add an event handler to the list of handlers. This will, on success, return - * a handle to the event handler object that was created, that can be used - * later to remove the handler using ecore_event_handler_del(). The @p type - * parameter is the integer of the event type that will trigger this callback - * to be called. The callback @p func is called when this event is processed - * and will be passed the event type, a pointer to the private event - * structure that is specific to that event type, and a data pointer that is - * provided in this call as the @p data parameter. - * - * When the callback @p func is called, it must return 1 or 0. If it returns - * 1 (or ECORE_CALLBACK_RENEW), It will keep being called as per normal, for - * each handler set up for that event type. If it returns 0 (or - * ECORE_CALLBACK_CANCEL), it will cease processing handlers for that particular - * event, so all handler set to handle that event type that have not already - * been called, will not be. - */ -EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, - Ecore_Event_Handler_Cb - func, const void *data) -{ - Ecore_Event_Handler *eh; - - if (!func) - return NULL; - if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) - return NULL; - eh = calloc(1, sizeof(Ecore_Event_Handler)); - if (!eh) - return NULL; - ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER); - eh->type = type; - eh->func = func; - eh->data = (void *) data; - if (type >= (event_handlers_num - 1)) { - int p_alloc_num; - - p_alloc_num = event_handlers_alloc_num; - event_handlers_num = type + 1; - if (event_handlers_num > event_handlers_alloc_num) { - Ecore_Event_Handler **new_handlers; - int i; - - event_handlers_alloc_num = - ((event_handlers_num + 16) / 16) * 16; - new_handlers = - realloc(event_handlers, - event_handlers_alloc_num * - sizeof(Ecore_Event_Handler *)); - if (!new_handlers) { - free(eh); - return NULL; - } - event_handlers = new_handlers; - for (i = p_alloc_num; i < event_handlers_alloc_num; - i++) - event_handlers[i] = NULL; - } - } - event_handlers[type] = - (Ecore_Event_Handler *) - eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), - EINA_INLIST_GET(eh)); - return eh; -} - -/** - * Delete an event handler. - * @param event_handler Event handler handle to delete - * @return Data passed to handler - * - * Delete a specified event handler from the handler list. On success this will - * delete the event handler and return the pointer passed as @p data when the - * handler was added by ecore_event_handler_add(). On failure NULL will be - * returned. Once a handler is deleted it will no longer be called. - */ -EAPI void *ecore_event_handler_del(Ecore_Event_Handler * event_handler) -{ - if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER)) { - ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER, - "ecore_event_handler_del"); - return NULL; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL); - event_handler->delete_me = 1; - event_handlers_delete_list = - eina_list_append(event_handlers_delete_list, event_handler); - return event_handler->data; -} - -static void _ecore_event_generic_free(void *data __UNUSED__, void *event) -{ - free(event); -} - -/** - * Add an event to the event queue. - * @param type The event type to add to the end of the event queue - * @param ev The private data structure for this event type - * @param func_free The function to be called to free this private structure - * @param data The data pointer to be passed to the free function - * @return A Handle for that event - * - * On success this function returns a handle to an event on the event queue, or - * NULL if it fails. If it succeeds, an event of type @p type will be added - * to the queue for processing by event handlers added by - * ecore_event_handler_add(). The @p ev parameter will be a pointer to the event - * private data that is specific to that event type. When the event is no - * longer needed, @p func_free will be called and passed the private structure - * pointer for cleaning up. If @p func_free is NULL, free() will be called - * with the private structure pointer. - * func_free is passed @p data as its data parameter. - */ -EAPI Ecore_Event *ecore_event_add(int type, void *ev, - Ecore_End_Cb func_free, void *data) -{ -/* if (!ev) return NULL;*/ - if (type <= ECORE_EVENT_NONE) - return NULL; - if (type >= event_id_max) - return NULL; - if ((ev) && (!func_free)) - func_free = _ecore_event_generic_free; - return _ecore_event_add(type, ev, func_free, data); -} - -/** - * Delete an event from the queue. - * @param event The event handle to delete - * @return The data pointer originally set for the event free function - * - * This deletes the event @p event from the event queue, and returns the - * @p data parameer originally set when adding it with ecore_event_add(). This - * does not immediately call the free function, and it may be called later on - * cleanup, and so if the free function depends on the data pointer to work, - * you should defer cleaning of this till the free function is called later. - */ -EAPI void *ecore_event_del(Ecore_Event * event) -{ - if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT)) { - ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, - "ecore_event_del"); - return NULL; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(event->delete_me, NULL); - event->delete_me = 1; - return event->data; -} - -/** - * Allocate a new event type id sensibly and return the new id. - * @return A new event type id. - * - * This function allocates a new event type id and returns it. Once an event - * type has been allocated it can never be de-allocated during the life of - * the program. There is no guarantee of the contents of this event ID, or how - * it is calculated, except that the ID will be unique to the current instance - * of the process. - */ -EAPI int ecore_event_type_new(void) -{ - event_id_max++; - return event_id_max - 1; -} - -/** - * Add a filter the current event queue. - * @param func_start Function to call just before filtering and return data - * @param func_filter Function to call on each event - * @param func_end Function to call after the queu has been filtered - * @param data Data to pass to the filter functions - * @return A filter handle - * - * This adds a filter to call callbacks to loop through the event queue and - * filter events out of the queue. On failure NULL is returned. On success a - * Filter handle is returned. Filters are called on the queue just before - * Event handler processing to try and remove redundant events. Just as - * processing starts @p func_start is called and passed the @p data pointer. - * This function returns a pointer that is used as loop_data that is now passed to - * @p func_filter as loop_data. @p func_filter is also passed @p data and the - * event type and private event structure. If this callback returns 0, the - * event is removed from the queue. If it returns 1, the event is kept. When - * processing is finished @p func_end is called and is passed the loop_data - * and @p data pointer to clean up. - */ -EAPI Ecore_Event_Filter *ecore_event_filter_add(Ecore_Data_Cb func_start, - Ecore_Filter_Cb - func_filter, - Ecore_End_Cb func_end, - const void *data) -{ - Ecore_Event_Filter *ef; - - if (!func_filter) - return NULL; - ef = calloc(1, sizeof(Ecore_Event_Filter)); - if (!ef) - return NULL; - ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER); - ef->func_start = func_start; - ef->func_filter = func_filter; - ef->func_end = func_end; - ef->data = (void *) data; - event_filters = - (Ecore_Event_Filter *) - eina_inlist_append(EINA_INLIST_GET(event_filters), - EINA_INLIST_GET(ef)); - return ef; -} - -/** - * Delete an event filter. - * @param ef The event filter handle - * @return The data set for the filter - * - * Delete a filter that has been added by its @p ef handle. On success this - * will return the data pointer set when this filter was added. On failure - * NULL is returned. - */ -EAPI void *ecore_event_filter_del(Ecore_Event_Filter * ef) -{ - if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER)) { - ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, - "ecore_event_filter_del"); - return NULL; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(ef->delete_me, NULL); - ef->delete_me = 1; - event_filters_delete_me = 1; - return ef->data; -} - -/** - * Return the current event type being handled. - * @return The current event type being handled if inside a handler callback - * - * If the program is currently inside an Ecore event handler callback this - * will return the type of the current event being processed. If Ecore is - * not inside an event handler, ECORE_EVENT_NONE is returned. - * - * This is useful when certain Ecore modules such as Ecore_Evas "swallow" - * events and not all the original information is passed on. In special cases - * this extra information may be useful or needed and using this call can let - * the program know if the event type being handled is one it wants to get more - * information about. - */ -EAPI int ecore_event_current_type_get(void) -{ - return ecore_raw_event_type; -} - -/** - * Return the current event type pointer handled. - * @return The current event pointer being handled if inside a handler callback - * - * If the program is currently inside an Ecore event handler callback this - * will return the pointer of the current event being processed. If Ecore is - * not inside an event handler, NULL will be returned. - * - * This is useful when certain Ecore modules such as Ecore_Evas "swallow" - * events and not all the original information is passed on. In special cases - * this extra information may be useful or needed and using this call can let - * the program access the event data if the type of the event is handled by - * the program. - */ -EAPI void *ecore_event_current_event_get(void) -{ - return ecore_raw_event_event; -} - -void _ecore_event_shutdown(void) -{ - int i; - Ecore_Event_Handler *eh; - Ecore_Event_Filter *ef; - - while (events) - _ecore_event_del(events); - event_current = NULL; - for (i = 0; i < event_handlers_num; i++) { - while ((eh = event_handlers[i])) { - event_handlers[i] = - (Ecore_Event_Handler *) - eina_inlist_remove(EINA_INLIST_GET - (event_handlers[i]), - EINA_INLIST_GET - (event_handlers[i])); - ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE); - if (!eh->delete_me) - free(eh); - } - } - EINA_LIST_FREE(event_handlers_delete_list, eh) - free(eh); - if (event_handlers) - free(event_handlers); - event_handlers = NULL; - event_handlers_num = 0; - event_handlers_alloc_num = 0; - while ((ef = event_filters)) { - event_filters = - (Ecore_Event_Filter *) - eina_inlist_remove(EINA_INLIST_GET(event_filters), - EINA_INLIST_GET(event_filters)); - ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE); - free(ef); - } - event_filters_delete_me = 0; - event_filter_current = NULL; - event_filter_event_current = NULL; -} - -int _ecore_event_exist(void) -{ - Ecore_Event *e; - EINA_INLIST_FOREACH(events, e) - if (!e->delete_me) - return 1; - return 0; -} - -Ecore_Event *_ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, - void *data) -{ - Ecore_Event *e; - - e = calloc(1, sizeof(Ecore_Event)); - if (!e) - return NULL; - ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT); - e->type = type; - e->event = ev; - e->func_free = func_free; - e->data = data; - if (inpurge > 0) { - purge_events = - (Ecore_Event *) - eina_inlist_append(EINA_INLIST_GET(purge_events), - EINA_INLIST_GET(e)); - events_num++; - } else { - events = - (Ecore_Event *) - eina_inlist_append(EINA_INLIST_GET(events), - EINA_INLIST_GET(e)); - events_num++; - } - return e; -} - -void *_ecore_event_del(Ecore_Event * event) -{ - void *data; - - data = event->data; - if (event->func_free) - event->func_free(event->data, event->event); - events = - (Ecore_Event *) eina_inlist_remove(EINA_INLIST_GET(events), - EINA_INLIST_GET(event)); - ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE); - free(event); - events_num--; - return data; -} - -static void _ecore_event_purge_deleted(void) -{ - Ecore_Event *itr = events; - - inpurge++; - while (itr) { - Ecore_Event *next = - (Ecore_Event *) EINA_INLIST_GET(itr)->next; - if ((!itr->references) && (itr->delete_me)) - _ecore_event_del(itr); - itr = next; - } - inpurge--; - while (purge_events) { - Ecore_Event *e = purge_events; - purge_events = - (Ecore_Event *) - eina_inlist_remove(EINA_INLIST_GET(purge_events), - EINA_INLIST_GET(purge_events)); - events = - (Ecore_Event *) - eina_inlist_append(EINA_INLIST_GET(events), - EINA_INLIST_GET(e)); - } -} - -static inline void _ecore_event_filters_apply() -{ - - if (!event_filter_current) { - /* regular main loop, start from head */ - event_filter_current = event_filters; - } else { - /* recursive main loop, continue from where we were */ - event_filter_current = - (Ecore_Event_Filter *) - EINA_INLIST_GET(event_filter_current)->next; - } - - while (event_filter_current) { - Ecore_Event_Filter *ef = event_filter_current; - - if (!ef->delete_me) { - ef->references++; - - if (ef->func_start) - ef->loop_data = ef->func_start(ef->data); - - if (!event_filter_event_current) { - /* regular main loop, start from head */ - event_filter_event_current = events; - } else { - /* recursive main loop, continue from where we were */ - event_filter_event_current = - (Ecore_Event *) - EINA_INLIST_GET - (event_filter_event_current)->next; - } - - while (event_filter_event_current) { - Ecore_Event *e = - event_filter_event_current; - - if (!ef-> - func_filter(ef->data, ef->loop_data, - e->type, e->event)) { - ecore_event_del(e); - } - - if (event_filter_event_current) /* may have changed in recursive main loops */ - event_filter_event_current = - (Ecore_Event *) - EINA_INLIST_GET - (event_filter_event_current)-> - next; - } - if (ef->func_end) - ef->func_end(ef->data, ef->loop_data); - - ef->references--; - } - - if (event_filter_current) /* may have changed in recursive main loops */ - event_filter_current = - (Ecore_Event_Filter *) - EINA_INLIST_GET(event_filter_current)->next; - } - if (event_filters_delete_me) { - int deleted_in_use = 0; - Ecore_Event_Filter *l; - for (l = event_filters; l;) { - Ecore_Event_Filter *ef = l; - l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)-> - next; - if (ef->delete_me) { - if (ef->references) { - deleted_in_use++; - continue; - } - - event_filters = - (Ecore_Event_Filter *) - eina_inlist_remove(EINA_INLIST_GET - (event_filters), - EINA_INLIST_GET - (ef)); - ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE); - free(ef); - } - } - if (!deleted_in_use) - event_filters_delete_me = 0; - } -} - -void _ecore_event_call(void) -{ - Eina_List *l, *l_next; - Ecore_Event_Handler *eh; - - _ecore_event_filters_apply(); - - if (!event_current) { - /* regular main loop, start from head */ - event_current = events; - event_handler_current = NULL; - } - - while (event_current) { - Ecore_Event *e = event_current; - int handle_count = 0; - - if (e->delete_me) { - event_current = - (Ecore_Event *) - EINA_INLIST_GET(event_current)->next; - continue; - } - - ecore_raw_event_type = e->type; - ecore_raw_event_event = e->event; - e->references++; - if ((e->type >= 0) && (e->type < event_handlers_num)) { - if (!event_handler_current) { - /* regular main loop, start from head */ - event_handler_current = - event_handlers[e->type]; - } else { - /* recursive main loop, continue from where we were */ - event_handler_current = - (Ecore_Event_Handler *) - EINA_INLIST_GET - (event_handler_current)->next; - } - - while ((event_handler_current) && (!e->delete_me)) { - Ecore_Event_Handler *eh = - event_handler_current; - if (!eh->delete_me) { - Eina_Bool ret; - - handle_count++; - - eh->references++; - ret = - eh->func(eh->data, e->type, - e->event); - eh->references--; - - if (!ret) { - event_handler_current = - NULL; - break; /* 0 == "call no further handlers" */ - } - } - - if (event_handler_current) /* may have changed in recursive main loops */ - event_handler_current = - (Ecore_Event_Handler *) - EINA_INLIST_GET - (event_handler_current)->next; - } - } - /* if no handlers were set for EXIT signal - then default is */ - /* to quit the main loop */ - if ((e->type == ECORE_EVENT_SIGNAL_EXIT) - && (handle_count == 0)) - ecore_main_loop_quit(); - e->references--; - e->delete_me = 1; - - if (event_current) /* may have changed in recursive main loops */ - event_current = - (Ecore_Event *) - EINA_INLIST_GET(event_current)->next; - } - - ecore_raw_event_type = ECORE_EVENT_NONE; - ecore_raw_event_event = NULL; - - _ecore_event_purge_deleted(); - - EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh) { - if (eh->references) - continue; - - event_handlers_delete_list = - eina_list_remove_list(event_handlers_delete_list, l); - - event_handlers[eh->type] = - (Ecore_Event_Handler *) - eina_inlist_remove(EINA_INLIST_GET - (event_handlers[eh->type]), - EINA_INLIST_GET(eh)); - ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE); - free(eh); - } -} - -EAPI void *_ecore_event_signal_user_new(void) -{ - Ecore_Event_Signal_User *e; - - e = calloc(1, sizeof(Ecore_Event_Signal_User)); - return e; -} - -void *_ecore_event_signal_hup_new(void) -{ - Ecore_Event_Signal_Hup *e; - - e = calloc(1, sizeof(Ecore_Event_Signal_Hup)); - return e; -} - -void *_ecore_event_signal_exit_new(void) -{ - Ecore_Event_Signal_Exit *e; - - e = calloc(1, sizeof(Ecore_Event_Signal_Exit)); - return e; -} - -void *_ecore_event_signal_power_new(void) -{ - Ecore_Event_Signal_Power *e; - - e = calloc(1, sizeof(Ecore_Event_Signal_Power)); - return e; -} - -void *_ecore_event_signal_realtime_new(void) -{ - return calloc(1, sizeof(Ecore_Event_Signal_Realtime)); -} diff --git a/tests/suite/ecore/src/lib/ecore_exe.c b/tests/suite/ecore/src/lib/ecore_exe.c deleted file mode 100644 index 883243a923..0000000000 --- a/tests/suite/ecore/src/lib/ecore_exe.c +++ /dev/null @@ -1,1805 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/time.h> -#include <sys/resource.h> - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <unistd.h> -#include <fcntl.h> - -#ifdef HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif - -#include "Ecore.h" -#include "ecore_private.h" - - - /* FIXME: Getting respawn to work - * - * There is no way that we can do anything about the internal state info of - * an external exe. The same can be said about the state of user code. User - * code in this context means the code that is using ecore_exe to manage exe's - * for it. - * - * Document that the exe must be respawnable, in other words, there is no - * state that it cannot regenerate by just killing it and starting it again. - * This includes state that the user code knows about, as the respawn is - * transparent to that code. On the other hand, maybe a respawn event might - * be useful, or maybe resend the currently non existent add event. For - * consistancy with ecore_con, an add event is good anyway. - * - * The Ecore_exe structure is reused for respawning, so that the (opaque) - * pointer held by the user remains valid. This means that the Ecore_Exe - * init and del functions may need to be split into two parts each to avoid - * duplicating code - common code part, and the rest. This implies that - * the unchanging members mentioned next should NEVER change. - * - * These structure members don't need to change - - * __list_data - we stay on the list - * ECORE_MAGIC - this is a constant - * data - passed in originally - * cmd - passed in originally - * flags - passed in originally - * - * These structure members need to change - - * tag - state that must be regenerated, zap it - * pid - it will be different - * child_fd_write - it will be different - * child_fd_read - it will be different - * child_fd_error - it will be different - * write_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes. - * read_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes. - * error_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes. - * - * Hmm, the read, write, and error buffers could be tricky. - * They are not atomic, and could be in a semi complete state. - * They fall into the "state must be regenerated" mentioned above. - * A respawn/add event should take care of it. - * - * These structure members need to change - - * write_data_buf - state that must be regenerated, zap it - * write_data_size - state that must be regenerated, zap it - * write_data_offset - state that must be regenerated, zap it - * read_data_buf - state that must be regenerated, zap it - * read_data_size - state that must be regenerated, zap it - * error_data_buf - state that must be regenerated, zap it - * error_data_size - state that must be regenerated, zap it - * close_write - state that must be regenerated, zap it - * - * There is the problem that an exe that fell over and needs respawning - * might keep falling over, keep needing to be respawned, and tie up system - * resources with the constant respawning. An exponentially increasing - * timeout (with maximum timeout) between respawns should take care of that. - * Although this is not a "contention for a resource" problem, the exe falling - * over may be, so a random element added to the timeout may help, and won't - * hurt. The user code may need to be informed that a timeout is in progress. - */ - -struct _Ecore_Exe { - EINA_INLIST; - ECORE_MAGIC; - pid_t pid; - void *data; - char *tag, *cmd; - Ecore_Exe_Flags flags; - Ecore_Fd_Handler *write_fd_handler; /* the fd_handler to handle write to child - if this was used, or NULL if not */ - Ecore_Fd_Handler *read_fd_handler; /* the fd_handler to handle read from child - if this was used, or NULL if not */ - Ecore_Fd_Handler *error_fd_handler; /* the fd_handler to handle errors from child - if this was used, or NULL if not */ - void *write_data_buf; /* a data buffer for data to write to the child - - * realloced as needed for more data and flushed when the fd handler says writes are possible - */ - int write_data_size; /* the size in bytes of the data buffer */ - int write_data_offset; /* the offset in bytes in the data buffer */ - void *read_data_buf; /* data read from the child awating delivery to an event */ - int read_data_size; /* data read from child in bytes */ - void *error_data_buf; /* errors read from the child awating delivery to an event */ - int error_data_size; /* errors read from child in bytes */ - int child_fd_write; /* fd to write TO to send data to the child */ - int child_fd_read; /* fd to read FROM when child has sent us (the parent) data */ - int child_fd_error; /* fd to read FROM when child has sent us (the parent) errors */ - int child_fd_write_x; /* fd to write TO to send data to the child */ - int child_fd_read_x; /* fd to read FROM when child has sent us (the parent) data */ - int child_fd_error_x; /* fd to read FROM when child has sent us (the parent) errors */ - Eina_Bool close_stdin:1; - - int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */ - - Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */ - void *doomsday_clock_dead; /* data for the doomsday clock */ - - Ecore_Exe_Cb pre_free_cb; -}; - - -/* TODO: Something to let people build a command line and does auto escaping - - * - * ecore_exe_snprintf() - * - * OR - * - * cmd = ecore_exe_comand_parameter_append(cmd, "firefox"); - * cmd = ecore_exe_comand_parameter_append(cmd, "http://www.foo.com/bar.html?baz=yes"); - * each parameter appended is one argument, and it gets escaped, quoted, and - * appended with a preceding space. The first is the command off course. - */ - -struct _ecore_exe_dead_exe { - pid_t pid; - char *cmd; -}; - -static inline void _ecore_exe_exec_it(const char *exe_cmd, - Ecore_Exe_Flags flags); -static Eina_Bool _ecore_exe_data_generic_handler(void *data, - Ecore_Fd_Handler * - fd_handler, - Ecore_Exe_Flags flags); -static Eina_Bool _ecore_exe_data_error_handler(void *data, - Ecore_Fd_Handler * - fd_handler); -static Eina_Bool _ecore_exe_data_read_handler(void *data, - Ecore_Fd_Handler * - fd_handler); -static Eina_Bool _ecore_exe_data_write_handler(void *data, - Ecore_Fd_Handler * - fd_handler); -static void _ecore_exe_flush(Ecore_Exe * exe); -static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, - void *ev); -static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid); -static Eina_Bool _ecore_exe_make_sure_its_dead(void *data); -static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data); -static Ecore_Exe_Event_Add *_ecore_exe_event_add_new(void); -static void _ecore_exe_event_add_free(void *data, void *ev); -static void _ecore_exe_dead_attach(Ecore_Exe * exe); - -EAPI int ECORE_EXE_EVENT_ADD = 0; -EAPI int ECORE_EXE_EVENT_DEL = 0; -EAPI int ECORE_EXE_EVENT_DATA = 0; -EAPI int ECORE_EXE_EVENT_ERROR = 0; - -static Ecore_Exe *exes = NULL; -static const char *shell = NULL; - -/* FIXME: This errno checking stuff should be put elsewhere for everybody to use. - * For now it lives here though, just to make testing easier. - */ -static int _ecore_exe_check_errno(int result, const char *file, int line); - -#define E_IF_NO_ERRNO(result, foo, ok) \ - while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \ - if (ok) - -#define E_NO_ERRNO(result, foo, ok) \ - while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)) == -1) sleep(1) - -#define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \ - if (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__))) - -static int _ecore_exe_check_errno(int result, const char *file, int line) -{ - int saved_errno = errno; - - if (result == -1) { - perror("*** errno reports "); -/* What is currently supported - - * - * pipe - * EFAULT Argument is not valid. - * EMFILE Too many file descriptors used by process. - * ENFILE Too many open files by system. - * read - * EAGAIN No data now, try again. - * EBADF This is not an fd that can be read. - * EFAULT This is not a valid buffer. - * EINTR Interupted by signal, try again. - * EINVAL This is not an fd that can be read. - * EIO I/O error. - * EISDIR This is a directory, and cannot be read. - * others Depending on what sort of thing we are reading from. - * close - * EBADF This is not an fd that can be closed. - * EINTR Interupted by signal, try again. - * EIO I/O error. - * dup2 - * EBADF This is not an fd that can be dup2'ed. - * EBUSY Race condition between open() and dup() - * EINTR Interupted by signal, try again. - * EMFILE Too many file descriptors used by process. - * fcntl - * EACCES, EAGAIN Locked or mapped by something else, try again later. - * EBADF This is not an fd that can be fcntl'ed. - * EDEADLK This will cause a deadlock. - * EFAULT This is not a valid lock. - * EINTR Interupted by signal, try again. - * EINVAL This is not a valid arg. - * EMFILE Too many file descriptors used by process. - * ENOLCK Problem getting a lock. - * EPERM Not allowed to do that. - * fsync - * EBADF This is not an fd that is open for writing. - * EINVAL, EROFS This is not an fd that can be fsynced. - * EIO I/O error. - * - * How to use it - - * int ok = 0; - * int result; - * - * E_IF_NO_ERRNO(result, foo(bar), ok) - * { - * E_IF_NO_ERRNO_NOLOOP(result, foo(bar), ok) - * { - * } - * } - * - * if (!ok) - * { - * // Something failed, cleanup. - * } - */ - switch (saved_errno) { - case EACCES: - case EAGAIN: - case EINTR: - { /* Not now, try later. */ - ERR("*** Must try again in %s @%u.", file, - line); - result = -1; - break; - } - case EMFILE: - case ENFILE: - case ENOLCK: - { /* Low on resources. */ - ERR("*** Low on resources in %s @%u.", - file, line); - result = 0; - break; - } - case EIO: - { /* I/O error. */ - ERR("*** I/O error in %s @%u.", file, - line); - result = 0; - break; - } - case EFAULT: - case EBADF: - case EINVAL: - case EROFS: - case EISDIR: - case EDEADLK: - case EPERM: - case EBUSY: - { /* Programmer fucked up. */ - ERR("*** NAUGHTY PROGRAMMER!!!\n" - "*** SPANK SPANK SPANK!!!\n" - "*** Now go fix your code in %s @%u. Tut tut tut!", - file, line); - result = 0; - break; - } - default: - { /* Unsupported errno code, please add this one. */ - ERR("*** NAUGHTY PROGRAMMER!!!\n" - "*** SPANK SPANK SPANK!!!\n" - "*** Unsupported errno code %d, please add this one.\n" - "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!", - saved_errno, __FILE__, __LINE__, file, - line); - result = 0; - break; - } - } - } else /* Everything is fine. */ - result = 1; - - errno = saved_errno; - return result; -} - -/** - * @defgroup Ecore_Exe_Basic_Group Process Spawning Functions - * - * Functions that deal with spawned processes. - */ - -static int run_pri = ECORE_EXE_PRIORITY_INHERIT; - -/** - * Sets the priority at which to launch processes - * - * This sets the priority of processes run by ecore_exe_run() and - * ecore_exe_pipe_run(). - * @li On Windows, the child process is created by default with the - * #ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling - * process is in #ECORE_EXE_WIN32_PRIORITY_IDLE or - * #ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the - * child process inherits this priority. - * @li On other platforms, if set to #ECORE_EXE_PRIORITY_INHERIT child - * processes inherits the priority of their parent. This is the default. - * - * @param pri value a Ecore_Exe_Win32_Priority value on Windows, -20 - * to 19 or ECORE_EXE_PRIORITY_INHERIT on other OS. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI void ecore_exe_run_priority_set(int pri) -{ - run_pri = pri; -} - -/** - * Gets the priority at which to launch processes - * - * This gets ths priority of launched processes. See - * ecore_exe_run_priority_set() for details. This just returns the value set - * by this call. - * - * @return the value set by ecore_exe_run_priority_set() - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI int ecore_exe_run_priority_get(void) -{ - return run_pri; -} - -/** - * Spawns a child process. - * - * This is now just a thin wrapper around ecore_exe_pipe_run() - * - * @param exe_cmd The command to run with @c /bin/sh. - * @param data Data to attach to the returned process handle. - * @return A process handle to the spawned process. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data) -{ -/* I'm just being paranoid again, leaving in the original code in case there is a problem. */ -#if 0 - Ecore_Exe *exe; - pid_t pid; - - if (!exe_cmd) - return NULL; - pid = fork(); - if (pid) { - exe = calloc(1, sizeof(Ecore_Exe)); - if (!exe) { - kill(pid, SIGKILL); - return NULL; - } - ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE); - exe->pid = pid; - exe->data = (void *) data; - exe->cmd = strdup(exe_cmd); - exes = _ecore_list2_append(exes, exe); - return exe; - } - _ecore_exe_exec_it(exe_cmd, 0); - exit(127); - return NULL; -#else - return ecore_exe_pipe_run(exe_cmd, 0, data); -#endif -} - -/** - * Spawns a child process with its stdin/out available for communication. - * - * This function forks and runs the given command using @c /bin/sh. - * - * Note that the process handle is only valid until a child process - * terminated event is received. After all handlers for the child process - * terminated event have been called, the handle will be freed by Ecore. - * - * This function does the same thing as ecore_exe_run(), but also makes the - * standard in and/or out as well as stderr from the child process available - * for reading or writing. To write use ecore_exe_send(). To read listen to - * ECORE_EXE_EVENT_DATA or ECORE_EXE_EVENT_ERROR events (set up handlers). - * Ecore may buffer read and error data until a newline character if asked - * for with the @p flags. All data will be included in the events (newlines - * will be replaced with NULLS if line buffered). ECORE_EXE_EVENT_DATA events - * will only happen if the process is run with ECORE_EXE_PIPE_READ enabled - * in the flags. The same with the error version. Writing will only be - * allowed with ECORE_EXE_PIPE_WRITE enabled in the flags. - * - * @param exe_cmd The command to run with @c /bin/sh. - * @param flags The flag parameters for how to deal with inter-process I/O - * @param data Data to attach to the returned process handle. - * @return A process handle to the spawned process. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, - Ecore_Exe_Flags flags, const void *data) -{ - Ecore_Exe *exe = NULL; - int statusPipe[2] = { -1, -1 }; - int errorPipe[2] = { -1, -1 }; - int readPipe[2] = { -1, -1 }; - int writePipe[2] = { -1, -1 }; - int n = 0; - int ok = 1; - int result; - - if (!exe_cmd) - return NULL; - exe = calloc(1, sizeof(Ecore_Exe)); - if (!exe) - return NULL; - - if ((flags & ECORE_EXE_PIPE_AUTO) - && (!(flags & ECORE_EXE_PIPE_ERROR)) - && (!(flags & ECORE_EXE_PIPE_READ))) - /* We need something to auto pipe. */ - flags |= ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR; - - exe->child_fd_error = -1; - exe->child_fd_read = -1; - exe->child_fd_write = -1; - exe->child_fd_error_x = -1; - exe->child_fd_read_x = -1; - exe->child_fd_write_x = -1; - - /* Create some pipes. */ - if (ok) { - E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok) { - } - } - if (ok && (flags & ECORE_EXE_PIPE_ERROR)) { - E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok) { - exe->child_fd_error = errorPipe[0]; - exe->child_fd_error_x = errorPipe[1]; - } - } - if (ok && (flags & ECORE_EXE_PIPE_READ)) { - E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok) { - exe->child_fd_read = readPipe[0]; - exe->child_fd_read_x = readPipe[1]; - } - } - if (ok && (flags & ECORE_EXE_PIPE_WRITE)) { - E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok) { - exe->child_fd_write = writePipe[1]; - exe->child_fd_write_x = writePipe[0]; - } - } - if (ok) { - pid_t pid = 0; - volatile int vfork_exec_errno = 0; - - /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */ - /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */ - pid = fork(); - - if (pid == -1) { - ERR("Failed to fork process"); - pid = 0; - } else if (pid == 0) { /* child */ - if (run_pri != ECORE_EXE_PRIORITY_INHERIT) { - if ((run_pri >= -20) && (run_pri <= 19)) - setpriority(PRIO_PROCESS, 0, - run_pri); - } - /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the - * second pipe if it's open. On the other hand, there was the - * Great FD Leak Scare of '06, so let's be paranoid. */ - if (ok && (flags & ECORE_EXE_PIPE_ERROR)) { - E_NO_ERRNO(result, close(STDERR_FILENO), - ok); - E_NO_ERRNO(result, - dup2(errorPipe[1], - STDERR_FILENO), ok); - } - if (ok && (flags & ECORE_EXE_PIPE_READ)) { - E_NO_ERRNO(result, close(STDOUT_FILENO), - ok); - E_NO_ERRNO(result, - dup2(readPipe[1], - STDOUT_FILENO), ok); - } - if (ok && (flags & ECORE_EXE_PIPE_WRITE)) { - E_NO_ERRNO(result, close(STDIN_FILENO), - ok); - E_NO_ERRNO(result, - dup2(writePipe[0], - STDIN_FILENO), ok); - } - - if (ok) { - /* Setup the status pipe. */ - E_NO_ERRNO(result, close(statusPipe[0]), - ok); - E_IF_NO_ERRNO(result, fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC), ok) { /* close on exec shows success */ - /* Run the actual command. */ - _ecore_exe_exec_it(exe_cmd, flags); /* no return */ - } - } - - /* Something went 'orribly wrong. */ - vfork_exec_errno = errno; - - /* Close the pipes. */ - if (flags & ECORE_EXE_PIPE_ERROR) - E_NO_ERRNO(result, close(errorPipe[1]), - ok); - if (flags & ECORE_EXE_PIPE_READ) - E_NO_ERRNO(result, close(readPipe[1]), ok); - if (flags & ECORE_EXE_PIPE_WRITE) - E_NO_ERRNO(result, close(writePipe[0]), - ok); - E_NO_ERRNO(result, close(statusPipe[1]), ok); - - _exit(-1); - } else { /* parent */ - - /* Close the unused pipes. */ - E_NO_ERRNO(result, close(statusPipe[1]), ok); - - /* FIXME: after having a good look at the current e fd - * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */ - /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO - * which is also linux specific so we probably don't want to - * do this as long as select() is working fine. the only time - * we really want to think of SIGIO async IO is when it all - * actually works basically everywhere and we can turn all - * IO into DMA async activities (i.e. you do a read() then - * the read is complete not on return but when you get a - * SIGIO - the read() just starts the transfer and it is - * completed in the background by DMA (or whatever mechanism - * the kernel choses)) */ - - /* Wait for it to start executing. */ - /* FIXME: this doesn't seem very nice - we sit and block - * waiting on a child process... even though it's just - * the segment between the fork() and the exec) it just feels - * wrong */ - for (;;) { - char buf; - - E_NO_ERRNO(result, - read(statusPipe[0], &buf, 1), - ok); - if (result == 0) { - if (vfork_exec_errno != 0) { - n = vfork_exec_errno; - ERR("Could not start \"%s\"", exe_cmd); - pid = 0; - } - break; - } - } - - /* Close the status pipe. */ - E_NO_ERRNO(result, close(statusPipe[0]), ok); - } - - if (pid) { - /* Setup the exe structure. */ - ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE); - exe->start_bytes = -1; - exe->end_bytes = -1; - exe->start_lines = -1; - exe->end_lines = -1; - exe->pid = pid; - exe->flags = flags; - exe->data = (void *) data; - if ((exe->cmd = strdup(exe_cmd))) { - if (flags & ECORE_EXE_PIPE_ERROR) { /* Setup the error stuff. */ - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_error, - F_SETFL, - O_NONBLOCK), - ok) { - } - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_error, - F_SETFD, - FD_CLOEXEC), - ok) { - } - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_error_x, - F_SETFD, - FD_CLOEXEC), - ok) { - } - { - exe->error_fd_handler = - ecore_main_fd_handler_add - (exe->child_fd_error, - ECORE_FD_READ, - _ecore_exe_data_error_handler, - exe, NULL, NULL); - if (!exe->error_fd_handler) - ok = 0; - } - } - if (ok && (flags & ECORE_EXE_PIPE_READ)) { /* Setup the read stuff. */ - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_read, - F_SETFL, - O_NONBLOCK), - ok) { - } - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_read, - F_SETFD, - FD_CLOEXEC), - ok) { - } - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_read_x, - F_SETFD, - FD_CLOEXEC), - ok) { - } - { - exe->read_fd_handler = - ecore_main_fd_handler_add - (exe->child_fd_read, - ECORE_FD_READ, - _ecore_exe_data_read_handler, - exe, NULL, NULL); - if (!exe->read_fd_handler) - ok = 0; - } - } - if (ok && (flags & ECORE_EXE_PIPE_WRITE)) { /* Setup the write stuff. */ - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_write, - F_SETFL, - O_NONBLOCK), - ok) { - } - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_write, - F_SETFD, - FD_CLOEXEC), - ok) { - } - E_IF_NO_ERRNO(result, - fcntl(exe-> - child_fd_write_x, - F_SETFD, - FD_CLOEXEC), - ok) { - } - { - exe->write_fd_handler = - ecore_main_fd_handler_add - (exe->child_fd_write, - ECORE_FD_WRITE, - _ecore_exe_data_write_handler, - exe, NULL, NULL); - if (exe->write_fd_handler) - ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */ - else - ok = 0; - } - } - - exes = - (Ecore_Exe *) - eina_inlist_append(EINA_INLIST_GET - (exes), - EINA_INLIST_GET - (exe)); - n = 0; - } else - ok = 0; - } else - ok = 0; - } - - if (!ok) { /* Something went wrong, so pull down everything. */ - if (exe->pid) - ecore_exe_terminate(exe); - IF_FN_DEL(ecore_exe_free, exe); - } else { - Ecore_Exe_Event_Add *e; - - e = _ecore_exe_event_add_new(); - e->exe = exe; - if (e) /* Send the event. */ - ecore_event_add(ECORE_EXE_EVENT_ADD, e, - _ecore_exe_event_add_free, NULL); - /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */ - } - - errno = n; - return exe; -} - -/** - * Defines a function to be called before really freeing the handle data. - * - * This might be useful for language bindings such as Python and Perl - * that need to deallocate wrappers associated with this handle. - * - * This handle should never be modified by this call. It should be - * considered informative only. All getters are valid when the given - * function is called back. - * - * @param exe The child process to attach the pre_free function. - * @param func The function to call before @a exe is freed. - */ -EAPI void -ecore_exe_callback_pre_free_set(Ecore_Exe * exe, Ecore_Exe_Cb func) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_callback_pre_free_set"); - return; - } - exe->pre_free_cb = func; -} - -/** - * Sends data to the given child process which it receives on stdin. - * - * This function writes to a child processes standard in, with unlimited - * buffering. This call will never block. It may fail if the system runs out - * of memory. - * - * @param exe The child process to send to - * @param data The data to send - * @param size The size of the data to send, in bytes - * @return EINA_TRUE if successful, EINA_FALSE on failure. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI Eina_Bool ecore_exe_send(Ecore_Exe * exe, const void *data, int size) -{ - void *buf; - - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send"); - return EINA_FALSE; - } - - if (exe->close_stdin) { - ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p", exe, size, data); - return EINA_FALSE; - } - - if (exe->child_fd_write == -1) { - ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! " - "Cannot send %d bytes from %p", exe, size, data); - return EINA_FALSE; - } - - buf = realloc(exe->write_data_buf, exe->write_data_size + size); - if (!buf) - return EINA_FALSE; - - exe->write_data_buf = buf; - memcpy((char *) exe->write_data_buf + exe->write_data_size, data, - size); - exe->write_data_size += size; - - if (exe->write_fd_handler) - ecore_main_fd_handler_active_set(exe->write_fd_handler, - ECORE_FD_WRITE); - - return EINA_TRUE; -} - -/** - * The stdin of the given child process will close when the write buffer is empty. - * - * @param exe The child process - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI void ecore_exe_close_stdin(Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_close_stdin"); - return; - } - exe->close_stdin = 1; -} - -/** - * Sets the auto pipe limits for the given process handle. On Windows - * this function does nothing. - * - * @param exe The given process handle. - * @param start_bytes limit of bytes at start of output to buffer. - * @param end_bytes limit of bytes at end of output to buffer. - * @param start_lines limit of lines at start of output to buffer. - * @param end_lines limit of lines at end of output to buffer. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI void -ecore_exe_auto_limits_set(Ecore_Exe * exe, int start_bytes, int end_bytes, - int start_lines, int end_lines) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_auto_limits_set"); - return; - } - /* FIXME: sanitize the input. */ - exe->start_bytes = start_bytes; - exe->end_bytes = end_bytes; - exe->start_lines = start_lines; - exe->end_lines = end_lines; - - /* FIXME: get this can of worms working. - * - * capture stderr & stdout internally - * - * raster and onefang keep moving the goal posts on this one. It started out as - * "show users the error output if an exe fails" and is rapidly approaching - * "alternative method of getting the data, poll vs event driven". Some serious - * thinking needs to be applied to this. Do we really want to go that far? If - * so, we should change the names. The basic design will probably remain the - * same which ever way we go. The constant goal post moving is probably due to - * generic design methods leading to feature creep as we inspired each other to - * more generic designs. It does seem like the closer we get to poll driven, - * the more issues and corner cases there are. - * - * Instead of doing the usual register an event handler thing, we are ecore_exe, - * we can take some short cuts. Don't send the events, just leave the exe buffers - * as is until the user asks for them, then return the event. - * - * start = 0, end = 0; clogged arteries get flushed, everything is ignored. - * start = -1, end = -1; clogged arteries get transferred to internal buffers. Actually, either == -1 means buffer everything. - * start = X, end = 0; buffer first X out of clogged arteries, flush and ignore rest. - * start = 0, end = X; circular buffer X - * start = X, end = Y; buffer first X out of clogged arteries, circular buffer Y from beginning. - * - * bytes vs lines, which ever one reaches the limit first. - * Before we go beyond the start+end limit, leave the end buffer empty, and store both in the start buffer, coz they overlap. - * After we pass the the start+end limit, insert "\n...\n" at the end of the start buffer, copy the rest to the end buffer, then store in the end buffer. - * - * Other issues - - * Spank programmer for polling data if polling is not turned on. - * Spank programmer for setting up event callbacks if polling is turned on. - * Spank programmer for freeing the event data if it came from the event system, as that autofrees. - * Spank the programmer if they try to set the limits bigger than what has been gathered & ignored already, coz they just lost data. - * Spank onefang and raster for opening this can of worms. - * Should we have separate out/err limits? - * Should we remove from the internal buffer the data that was delivered already? - * If so, what to do about limits, start, and end? They could loose their meaning. - */ -} - -/** - * Gets the auto pipe data for the given process handle - * - * @param exe The given process handle. - * @param flags Is this a ECORE_EXE_PIPE_READ or ECORE_EXE_PIPE_ERROR? - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI Ecore_Exe_Event_Data *ecore_exe_event_data_get(Ecore_Exe * exe, - Ecore_Exe_Flags flags) -{ - Ecore_Exe_Event_Data *e = NULL; - int is_buffered = 0; - unsigned char *inbuf; - int inbuf_num; - - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_event_data_get"); - return NULL; - } - - /* Sort out what sort of event we are. */ - if (flags & ECORE_EXE_PIPE_READ) { - flags = ECORE_EXE_PIPE_READ; - if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED) - is_buffered = 1; - } else { - flags = ECORE_EXE_PIPE_ERROR; - if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED) - is_buffered = 1; - } - - /* Get the data. */ - if (flags & ECORE_EXE_PIPE_READ) { - inbuf = exe->read_data_buf; - inbuf_num = exe->read_data_size; - exe->read_data_buf = NULL; - exe->read_data_size = 0; - } else { - inbuf = exe->error_data_buf; - inbuf_num = exe->error_data_size; - exe->error_data_buf = NULL; - exe->error_data_size = 0; - } - - e = calloc(1, sizeof(Ecore_Exe_Event_Data)); - if (e) { - e->exe = exe; - e->data = inbuf; - e->size = inbuf_num; - - if (is_buffered) { /* Deal with line buffering. */ - int max = 0; - int count = 0; - int i; - int last = 0; - char *c; - - c = (char *) inbuf; - for (i = 0; i < inbuf_num; i++) { /* Find the lines. */ - if (inbuf[i] == '\n') { - if (count >= max) { - /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */ - max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */ - e->lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */ - } - /* raster said to leave the line endings as line endings, however - - * This is line buffered mode, we are not dealing with binary here, but lines. - * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format. - * Thus the user is most likely gonna deal with this text as strings. - * Thus the user is most likely gonna pass this data to str functions. - * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0' - * We are handing them the string length as a convenience. - * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough. - * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer. - * Let's make it easy on them to use these as standard C strings. - * - * onefang is proud to announce that he has just set a new personal record for the - * most over documentation of a simple assignment statement. B-) - */ - inbuf[i] = '\0'; - e->lines[count].line = c; - e->lines[count].size = i - last; - last = i + 1; - c = (char *) &inbuf[last]; - count++; - } - } - if (count == 0) { /* No lines to send, cancel the event. */ - _ecore_exe_event_exe_data_free(NULL, e); - e = NULL; - } else { /* NULL terminate the array, so that people know where the end is. */ - - e->lines[count].line = NULL; - e->lines[count].size = 0; - } - if (i > last) { /* Partial line left over, save it for next time. */ - if (e) - e->size = last; - if (flags & ECORE_EXE_PIPE_READ) { - exe->read_data_size = i - last; - exe->read_data_buf = - malloc(exe->read_data_size); - memcpy(exe->read_data_buf, c, - exe->read_data_size); - } else { - exe->error_data_size = i - last; - exe->error_data_buf = - malloc(exe->error_data_size); - memcpy(exe->error_data_buf, c, - exe->error_data_size); - } - } - } - } - - return e; -} - -/** - * Sets the string tag for the given process handle - * - * @param exe The given process handle. - * @param tag The string tag to set on the process handle. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI void ecore_exe_tag_set(Ecore_Exe * exe, const char *tag) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_tag_set"); - return; - } - IF_FREE(exe->tag); - if (tag) - exe->tag = strdup(tag); - else - exe->tag = NULL; -} - -/** - * Retrieves the tag attached to the given process handle. There is no need to - * free it as it just returns the internal pointer value. This value is only - * valid as long as the @p exe is valid or until the tag is set to something - * else on this @p exe. - * - * @param exe The given process handle. - * @return The string attached to @p exe. It is a handle to existing - * internal string and should not be modified, use - * ecore_exe_tag_set() to change it. It might be @c NULL. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI const char *ecore_exe_tag_get(const Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_tag_get"); - return NULL; - } - return exe->tag; -} - -/** - * Frees the given process handle. - * - * Note that the process that the handle represents is unaffected by this - * function. - * - * @param exe The given process handle. - * @return The data attached to the handle when @ref ecore_exe_run was - * called. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI void *ecore_exe_free(Ecore_Exe * exe) -{ - void *data; - int ok = 0; - int result; - - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free"); - return NULL; - } - - data = exe->data; - - if (exe->pre_free_cb) - exe->pre_free_cb(data, exe); - - if (exe->doomsday_clock) { - struct _ecore_exe_dead_exe *dead; - - ecore_timer_del(exe->doomsday_clock); - exe->doomsday_clock = NULL; - dead = exe->doomsday_clock_dead; - if (dead) { - IF_FREE(dead->cmd); - free(dead); - exe->doomsday_clock_dead = NULL; - } - } - IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler); - IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler); - IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler); - if (exe->child_fd_write_x != -1) - E_NO_ERRNO(result, close(exe->child_fd_write_x), ok); - if (exe->child_fd_read_x != -1) - E_NO_ERRNO(result, close(exe->child_fd_read_x), ok); - if (exe->child_fd_error_x != -1) - E_NO_ERRNO(result, close(exe->child_fd_error_x), ok); - if (exe->child_fd_write != -1) - E_NO_ERRNO(result, close(exe->child_fd_write), ok); - if (exe->child_fd_read != -1) - E_NO_ERRNO(result, close(exe->child_fd_read), ok); - if (exe->child_fd_error != -1) - E_NO_ERRNO(result, close(exe->child_fd_error), ok); - IF_FREE(exe->write_data_buf); - IF_FREE(exe->read_data_buf); - IF_FREE(exe->error_data_buf); - IF_FREE(exe->cmd); - - exes = - (Ecore_Exe *) eina_inlist_remove(EINA_INLIST_GET(exes), - EINA_INLIST_GET(exe)); - ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE); - IF_FREE(exe->tag); - free(exe); - return data; -} - -/** - * Frees the given event data. - * - * @param e The given event data. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI void ecore_exe_event_data_free(Ecore_Exe_Event_Data * e) -{ - if (!e) - return; - IF_FREE(e->lines); - IF_FREE(e->data); - free(e); -} - -/** - * Retrieves the process ID of the given spawned process. - * @param exe Handle to the given spawned process. - * @return The process ID on success. @c -1 otherwise. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI pid_t ecore_exe_pid_get(const Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_pid_get"); - return -1; - } - return exe->pid; -} - -/** - * Retrieves the command of the given spawned process. - * @param exe Handle to the given spawned process. - * @return The command on success. NULL otherwise. This string is the - * pointer to the internal value and must not be modified in - * any way. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI const char *ecore_exe_cmd_get(const Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_cmd_get"); - return NULL; - } - return exe->cmd; -} - -/** - * Retrieves the data attached to the given process handle. - * @param exe The given process handle. - * @return The data pointer attached to @p exe Given to - * ecore_exe_run() or ecore_exe_pipe_run() - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI void *ecore_exe_data_get(const Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_data_get"); - return NULL; - } - return exe->data; -} - -/** - * Retrieves the flags attached to the given process handle. - * @param exe The given process handle. - * @return The flags attached to @p exe. - * @ingroup Ecore_Exe_Basic_Group - */ -EAPI Ecore_Exe_Flags ecore_exe_flags_get(const Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_data_get"); - return 0; - } - return exe->flags; -} - -/** - * @defgroup Ecore_Exe_Signal_Group Spawned Process Signal Functions - * - * Functions that send signals to spawned processes. - */ - -/** - * Pauses the given process by sending it a @c SIGSTOP signal. - * @param exe Process handle to the given process. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_pause(Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause"); - return; - } - kill(exe->pid, SIGSTOP); -} - -/** - * Continues the given paused process by sending it a @c SIGCONT signal. - * @param exe Process handle to the given process. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_continue(Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_continue"); - return; - } - kill(exe->pid, SIGCONT); -} - -/** - * Sends the given spawned process a interrupt (@c SIGINT) signal. - * @param exe Process handle to the given process. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_interrupt(Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_interrupt"); - return; - } - _ecore_exe_dead_attach(exe); - kill(exe->pid, SIGINT); -} - -/** - * Sends the given spawned process a quit (@c SIGQUIT) signal. - * @param exe Process handle to the given process. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_quit(Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_quit"); - return; - } - _ecore_exe_dead_attach(exe); - kill(exe->pid, SIGQUIT); -} - -/** - * Sends the given spawned process a terminate (@c SIGTERM) signal. - * @param exe Process handle to the given process. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_terminate(Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, - "ecore_exe_terminate"); - return; - } - _ecore_exe_dead_attach(exe); - INF("Sending TERM signal to %s (%d).", exe->cmd, exe->pid); - kill(exe->pid, SIGTERM); -} - -/** - * Kills the given spawned process by sending it a @c SIGKILL signal. - * @param exe Process handle to the given process. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_kill(Ecore_Exe * exe) -{ - struct _ecore_exe_dead_exe *dead; - - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill"); - return; - } - - dead = calloc(1, sizeof(struct _ecore_exe_dead_exe)); - if (dead) { - dead->pid = exe->pid; - dead->cmd = strdup(exe->cmd); - IF_FN_DEL(ecore_timer_del, exe->doomsday_clock); - exe->doomsday_clock = - ecore_timer_add(10.0, - _ecore_exe_make_sure_its_really_dead, - dead); - } - - INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid); - kill(exe->pid, SIGKILL); -} - -/** - * Sends a @c SIGUSR signal to the given spawned process. - * @param exe Process handle to the given process. - * @param num The number user signal to send. Must be either 1 or 2, or - * the signal will be ignored. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_signal(Ecore_Exe * exe, int num) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal"); - return; - } - if (num == 1) - kill(exe->pid, SIGUSR1); - else if (num == 2) - kill(exe->pid, SIGUSR2); -} - -/** - * Sends a @c SIGHUP signal to the given spawned process. - * @param exe Process handle to the given process. - * @ingroup Ecore_Exe_Signal_Group - */ -EAPI void ecore_exe_hup(Ecore_Exe * exe) -{ - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup"); - return; - } - kill(exe->pid, SIGHUP); -} - -static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid) -{ - Ecore_Exe *exe = NULL; - - /* FIXME: There is no nice, safe, OS independent way to tell if a - * particular PID is still alive. I have written code to do so - * for my urunlevel busybox applet (http://urunlevel.sourceforge.net/), - * but it's for linux only, and still not guaranteed. - * - * So for now, we just check that a valid Ecore_Exe structure - * exists for it. Even that is not a guarantee, as the structure - * can be freed without killing the process. - * - * I think we can safely put exe's into two categories, those users - * that care about the life of the exe, and the run and forget type. - * The run and forget type starts up the exe, then free's the - * Ecore_Exe structure straight away. They can never call any of - * the functions that can call this, so we don't worry about them. - * - * Those user's that care about the life of exe's will keep the - * Ecore_Exe structure around, terminate them eventually, or - * register for exit events. For these ones the assumption - * that valid Ecore_Exe struct == live exe is almost valid. - * - * I will probably copy my urunlevel code into here someday. - */ - exe = _ecore_exe_find(pid); - if (exe) { - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) - exe = NULL; - } - - return exe; -} - -static Eina_Bool _ecore_exe_make_sure_its_dead(void *data) -{ - struct _ecore_exe_dead_exe *dead; - - dead = data; - if (dead) { - Ecore_Exe *exe = NULL; - - if ((exe = _ecore_exe_is_it_alive(dead->pid))) { - if (dead->cmd) - INF("Sending KILL signal to allegedly dead %s (%d).", dead->cmd, dead->pid); - else - INF("Sending KILL signal to allegedly dead PID %d.", dead->pid); - exe->doomsday_clock = - ecore_timer_add(10.0, - _ecore_exe_make_sure_its_really_dead, - dead); - kill(dead->pid, SIGKILL); - } else { - IF_FREE(dead->cmd); - free(dead); - } - } - return ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data) -{ - struct _ecore_exe_dead_exe *dead; - - dead = data; - if (dead) { - Ecore_Exe *exe = NULL; - - if ((exe = _ecore_exe_is_it_alive(dead->pid))) { - ERR("RUN! The zombie wants to eat your brains! And your CPU!"); - if (dead->cmd) - INF("%s (%d) is not really dead.", - dead->cmd, dead->pid); - else - INF("PID %d is not really dead.", - dead->pid); - exe->doomsday_clock = NULL; - } - IF_FREE(dead->cmd); - free(dead); - } - return ECORE_CALLBACK_CANCEL; -} - -void _ecore_exe_init(void) -{ - ECORE_EXE_EVENT_ADD = ecore_event_type_new(); - ECORE_EXE_EVENT_DEL = ecore_event_type_new(); - ECORE_EXE_EVENT_DATA = ecore_event_type_new(); - ECORE_EXE_EVENT_ERROR = ecore_event_type_new(); -} - -void _ecore_exe_shutdown(void) -{ - while (exes) - ecore_exe_free(exes); -} - -Ecore_Exe *_ecore_exe_find(pid_t pid) -{ - Ecore_Exe *exe; - - EINA_INLIST_FOREACH(exes, exe) { - if (exe->pid == pid) - return exe; - } - return NULL; -} - -Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe * exe) -{ - return exe->doomsday_clock; -} - -void _ecore_exe_doomsday_clock_set(Ecore_Exe * exe, Ecore_Timer * dc) -{ - exe->doomsday_clock = dc; -} - -static inline void -_ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags) -{ - char use_sh = 1; - char *buf = NULL; - char **args = NULL; - int save_errno = 0; - - /* So what is this doing? - * - * We are trying to avoid wrapping the exe call with /bin/sh -c. - * We conservatively search for certain shell meta characters, - * If we don't find them, we can call the exe directly. - */ - if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#")) { - char *token; - char pre_command = 1; - int num_tokens = 0; - - if (!(buf = strdup(exe_cmd))) - return; - - token = strtok(buf, " \t\n\v"); - while (token) { - if (token[0] == '~') - break; - if (pre_command) { - if (token[0] == '[') - break; - if (strchr(token, '=')) - break; - else - pre_command = 0; - } - num_tokens++; - token = strtok(NULL, " \t\n\v"); - } - IF_FREE(buf); - if ((!token) && (num_tokens)) { - int i = 0; - - if (!(buf = strdup(exe_cmd))) - return; - - token = strtok(buf, " \t\n\v"); - use_sh = 0; - if (! - (args = - (char **) calloc(num_tokens + 1, - sizeof(char *)))) { - IF_FREE(buf); - return; - } - for (i = 0; i < num_tokens; i++) { - if (token) - args[i] = token; - token = strtok(NULL, " \t\n\v"); - } - args[num_tokens] = NULL; - } - } - - if (!(flags & ECORE_EXE_NOT_LEADER)) - setsid(); - if ((flags & ECORE_EXE_USE_SH)) { - errno = 0; - execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *) NULL); - } else if (use_sh) { /* We have to use a shell to run this. */ - if (!shell) { /* Find users preferred shell. */ - shell = getenv("SHELL"); - if (!shell) - shell = "/bin/sh"; - } - errno = 0; - execl(shell, shell, "-c", exe_cmd, (char *) NULL); - } else { /* We can run this directly. */ - errno = 0; - execvp(args[0], args); - } - - save_errno = errno; - IF_FREE(buf); - IF_FREE(args); - errno = save_errno; - return; -} - -static Eina_Bool -_ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler * fd_handler, - Ecore_Exe_Flags flags) -{ - Ecore_Exe *exe; - int child_fd; - int event_type; - - exe = data; - - /* Sort out what sort of handler we are. */ - if (flags & ECORE_EXE_PIPE_READ) { - flags = ECORE_EXE_PIPE_READ; - event_type = ECORE_EXE_EVENT_DATA; - child_fd = exe->child_fd_read; - } else { - flags = ECORE_EXE_PIPE_ERROR; - event_type = ECORE_EXE_EVENT_ERROR; - child_fd = exe->child_fd_error; - } - - if ((fd_handler) - && - (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))) - { - unsigned char *inbuf; - int inbuf_num; - - /* Get any left over data from last time. */ - if (flags & ECORE_EXE_PIPE_READ) { - inbuf = exe->read_data_buf; - inbuf_num = exe->read_data_size; - exe->read_data_buf = NULL; - exe->read_data_size = 0; - } else { - inbuf = exe->error_data_buf; - inbuf_num = exe->error_data_size; - exe->error_data_buf = NULL; - exe->error_data_size = 0; - } - - for (;;) { - int num, lost_exe; - char buf[READBUFSIZ]; - - lost_exe = 0; - errno = 0; - if ((num = read(child_fd, buf, READBUFSIZ)) < 1) - /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE - * (currently 64k) to inbuf, use that instead of buf, and - * save ourselves a memcpy(). */ - { - lost_exe = ((errno == EIO) || - (errno == EBADF) || - (errno == EPIPE) || - (errno == EINVAL) - || (errno == ENOSPC)); - if ((errno != EAGAIN) && (errno != EINTR)) - perror - ("_ecore_exe_generic_handler() read problem "); - } - if (num > 0) { /* data got read. */ - inbuf = realloc(inbuf, inbuf_num + num); - memcpy(inbuf + inbuf_num, buf, num); - inbuf_num += num; - } else { /* No more data to read. */ - if (inbuf) { - Ecore_Exe_Event_Data *e; - - /* Stash the data away for later. */ - if (flags & ECORE_EXE_PIPE_READ) { - exe->read_data_buf = inbuf; - exe->read_data_size = - inbuf_num; - } else { - exe->error_data_buf = - inbuf; - exe->error_data_size = - inbuf_num; - } - - if (! - (exe-> - flags & ECORE_EXE_PIPE_AUTO)) - { - e = ecore_exe_event_data_get(exe, flags); - if (e) /* Send the event. */ - ecore_event_add - (event_type, e, - _ecore_exe_event_exe_data_free, - NULL); - } - } - if (lost_exe) { - if (flags & ECORE_EXE_PIPE_READ) { - if (exe->read_data_size) - INF("There are %d bytes left unsent from the dead exe %s.", exe->read_data_size, exe->cmd); - } else { - if (exe->error_data_size) - INF("There are %d bytes left unsent from the dead exe %s.", exe->error_data_size, exe->cmd); - } - /* Thought about this a bit. If the exe has actually - * died, this won't do any harm as it must have died - * recently and the pid has not had a chance to recycle. - * It is also a paranoid catchall, coz the usual ecore_signal - * mechenism should kick in. But let's give it a good - * kick in the head anyway. - */ - ecore_exe_terminate(exe); - } - break; - } - } - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler * fd_handler) -{ - return _ecore_exe_data_generic_handler(data, fd_handler, - ECORE_EXE_PIPE_ERROR); -} - -static Eina_Bool -_ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler * fd_handler) -{ - return _ecore_exe_data_generic_handler(data, fd_handler, - ECORE_EXE_PIPE_READ); -} - -static Eina_Bool -_ecore_exe_data_write_handler(void *data, - Ecore_Fd_Handler * fd_handler __UNUSED__) -{ - Ecore_Exe *exe; - - exe = data; - if ((exe->write_fd_handler) && - (ecore_main_fd_handler_active_get - (exe->write_fd_handler, ECORE_FD_WRITE))) - _ecore_exe_flush(exe); - - /* If we have sent all there is to send, and we need to close the pipe, then close it. */ - if ((exe->close_stdin == 1) - && (exe->write_data_size == exe->write_data_offset)) { - int ok = 0; - int result; - - INF("Closing stdin for %s", exe->cmd); - /* if (exe->child_fd_write != -1) E_NO_ERRNO(result, fsync(exe->child_fd_write), ok); This a) doesn't work, and b) isn't needed. */ - IF_FN_DEL(ecore_main_fd_handler_del, - exe->write_fd_handler); - if (exe->child_fd_write != -1) - E_NO_ERRNO(result, close(exe->child_fd_write), ok); - exe->child_fd_write = -1; - IF_FREE(exe->write_data_buf); - } - - return ECORE_CALLBACK_RENEW; -} - -static void _ecore_exe_flush(Ecore_Exe * exe) -{ - int count; - - /* check whether we need to write anything at all. */ - if ((exe->child_fd_write == -1) || (!exe->write_data_buf)) - return; - if (exe->write_data_size == exe->write_data_offset) - return; - - count = write(exe->child_fd_write, - (char *) exe->write_data_buf + - exe->write_data_offset, - exe->write_data_size - exe->write_data_offset); - if (count < 1) { - if (errno == EIO || errno == EBADF || errno == EPIPE || errno == EINVAL || errno == ENOSPC) { /* we lost our exe! */ - ecore_exe_terminate(exe); - if (exe->write_fd_handler) - ecore_main_fd_handler_active_set(exe-> - write_fd_handler, - 0); - } - } else { - exe->write_data_offset += count; - if (exe->write_data_offset >= exe->write_data_size) { /* Nothing left to write, clean up. */ - exe->write_data_size = 0; - exe->write_data_offset = 0; - IF_FREE(exe->write_data_buf); - if (exe->write_fd_handler) - ecore_main_fd_handler_active_set(exe-> - write_fd_handler, - 0); - } - } -} - -static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev) -{ - Ecore_Exe_Event_Data *e; - - e = ev; - ecore_exe_event_data_free(e); -} - -static Ecore_Exe_Event_Add *_ecore_exe_event_add_new(void) -{ - Ecore_Exe_Event_Add *e; - - e = calloc(1, sizeof(Ecore_Exe_Event_Add)); - return e; -} - -static void _ecore_exe_event_add_free(void *data __UNUSED__, void *ev) -{ - Ecore_Exe_Event_Add *e; - - e = ev; - free(e); -} - -void *_ecore_exe_event_del_new(void) -{ - Ecore_Exe_Event_Del *e; - - e = calloc(1, sizeof(Ecore_Exe_Event_Del)); - return e; -} - -void _ecore_exe_event_del_free(void *data __UNUSED__, void *ev) -{ - Ecore_Exe_Event_Del *e; - - e = ev; - if (e->exe) - ecore_exe_free(e->exe); - free(e); -} - -static void _ecore_exe_dead_attach(Ecore_Exe * exe) -{ - struct _ecore_exe_dead_exe *dead; - - if (exe->doomsday_clock_dead) - return; - dead = calloc(1, sizeof(struct _ecore_exe_dead_exe)); - if (dead) { - dead->pid = exe->pid; - dead->cmd = strdup(exe->cmd); - IF_FN_DEL(ecore_timer_del, exe->doomsday_clock); - exe->doomsday_clock = - ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, - dead); - exe->doomsday_clock_dead = dead; - } -} diff --git a/tests/suite/ecore/src/lib/ecore_getopt.c b/tests/suite/ecore/src/lib/ecore_getopt.c deleted file mode 100644 index 1fdd233693..0000000000 --- a/tests/suite/ecore/src/lib/ecore_getopt.c +++ /dev/null @@ -1,1786 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#elif defined __GNUC__ -#define alloca __builtin_alloca -#elif defined _AIX -#define alloca __alloca -#elif defined _MSC_VER -#include <malloc.h> -#define alloca _alloca -#else -#include <stddef.h> -#ifdef __cplusplus -extern "C" -#endif -void *alloca(size_t); -#endif - -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> - -#ifdef ENABLE_NLS -#include <libintl.h> -#else -#define gettext(x) (x) -#define dgettext(domain, x) (x) -#endif - -#define _(x) dgettext("ecore", x) - -#ifdef _WIN32_WCE -#include <Evil.h> -#endif - -#include "Ecore.h" -#include "Ecore_Getopt.h" - -static const char *prog = NULL; -static char **argv = NULL; -static int argc = 0; -static int cols = 80; -static int helpcol = 80 / 3; - -static void -_ecore_getopt_help_print_replace_program(FILE * fp, - const Ecore_Getopt * - parser __UNUSED__, - const char *text) -{ - do { - const char *d = strchr(text, '%'); - - if (!d) { - fputs(text, fp); - break; - } - - if (fwrite(text, 1, d - text, fp) != (size_t) (d - text)) - return; - d++; - if (strncmp(d, "prog", sizeof("prog") - 1) == 0) { - fputs(prog ? prog : "???", fp); - d += sizeof("prog") - 1; - } else { - if (d[0] == '%') - d++; - fputc('%', fp); - } - - text = d; - } - while (text[0] != '\0'); - - fputc('\n', fp); -} - -static void _ecore_getopt_version(FILE * fp, const Ecore_Getopt * parser) -{ - fputs(_("Version:"), fp); - fputc(' ', fp); - _ecore_getopt_help_print_replace_program(fp, parser, - parser->version); -} - -static void -_ecore_getopt_help_usage(FILE * fp, const Ecore_Getopt * parser) -{ - fputs(_("Usage:"), fp); - fputc(' ', fp); - - if (!parser->usage) { - fprintf(fp, _("%s [options]\n"), prog); - return; - } - - _ecore_getopt_help_print_replace_program(fp, parser, - gettext(parser->usage)); -} - -static int -_ecore_getopt_help_line(FILE * fp, const int base, const int total, - int used, const char *text, int len) -{ - int linebreak = 0; - do { - /* process line considering spaces (new line and tabs are spaces!) */ - while ((used < total) && (len > 0)) { - const char *space = NULL; - int i, todo; - - todo = total - used; - if (todo > len) - todo = len; - - for (i = 0; i < todo; i++) - if (isspace(text[i])) { - space = text + i; - break; - } - - if (space) { - i = fwrite(text, 1, i, fp); - i++; - text += i; - len -= i; - used += i; - - if (linebreak) { - linebreak = 0; - continue; - } - - if (space[0] == '\n') - break; - else if (space[0] == '\t') { - int c; - - used--; - c = ((used / 8) + 1) * 8; - if (c < total) { - for (; used < c; used++) - fputc(' ', fp); - } else { - text--; - len++; - break; - } - } else if (used < total) - fputc(space[0], fp); - } else { - i = fwrite(text, 1, i, fp); - text += i; - len -= i; - used += i; - } - linebreak = 0; - } - if (len <= 0) - break; - linebreak = 1; - fputc('\n', fp); - for (used = 0; used < base; used++) - fputc(' ', fp); - } - while (1); - - return used; -} - -static void -_ecore_getopt_help_description(FILE * fp, const Ecore_Getopt * parser) -{ - const char *p, *prg, *ver; - int used, prglen, verlen; - - p = gettext(parser->description); - if (!p) - return; - - fputc('\n', fp); - - prg = prog ? prog : "???"; - ver = parser->version ? parser->version : "???"; - - prglen = strlen(prg); - verlen = strlen(ver); - - used = 0; - - do { - const char *d = strchr(p, '%'); - - if (!d) { - _ecore_getopt_help_line(fp, 0, cols, used, p, - strlen(p)); - break; - } - - used = - _ecore_getopt_help_line(fp, 0, cols, used, p, d - p); - d++; - if (strncmp(d, "prog", sizeof("prog") - 1) == 0) { - used = - _ecore_getopt_help_line(fp, 0, cols, used, prg, - prglen); - d += sizeof("prog") - 1; - } else if (strncmp(d, "version", sizeof("version") - 1) == - 0) { - used = - _ecore_getopt_help_line(fp, 0, cols, used, ver, - verlen); - d += sizeof("version") - 1; - } else { - if (d[0] == '%') - d++; - used = - _ecore_getopt_help_line(fp, 0, cols, used, "%", - 1); - } - - p = d; - } - while (p[0] != '\0'); - - fputs("\n\n", fp); -} - -static void _ecore_getopt_copyright(FILE * fp, const Ecore_Getopt * parser) -{ - const char *txt = gettext(parser->copyright); - fputs(_("Copyright:"), fp); - fputs("\n ", fp); - _ecore_getopt_help_line(fp, 3, cols, 3, txt, strlen(txt)); - fputc('\n', fp); -} - -static void _ecore_getopt_license(FILE * fp, const Ecore_Getopt * parser) -{ - const char *txt = gettext(parser->license); - fputs(_("License:"), fp); - fputs("\n ", fp); - _ecore_getopt_help_line(fp, 3, cols, 3, txt, strlen(txt)); - fputc('\n', fp); -} - -static Ecore_Getopt_Desc_Arg_Requirement -_ecore_getopt_desc_arg_requirement(const Ecore_Getopt_Desc * desc) -{ - switch (desc->action) { - case ECORE_GETOPT_ACTION_STORE: - return desc->action_param.store.arg_req; - case ECORE_GETOPT_ACTION_STORE_CONST: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO; - case ECORE_GETOPT_ACTION_STORE_TRUE: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO; - case ECORE_GETOPT_ACTION_STORE_FALSE: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO; - case ECORE_GETOPT_ACTION_CHOICE: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES; - case ECORE_GETOPT_ACTION_APPEND: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES; - case ECORE_GETOPT_ACTION_COUNT: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO; - case ECORE_GETOPT_ACTION_CALLBACK: - return desc->action_param.callback.arg_req; - case ECORE_GETOPT_ACTION_HELP: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO; - case ECORE_GETOPT_ACTION_VERSION: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO; - default: - return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO; - } -} - -static void -_ecore_getopt_help_desc_setup_metavar(const Ecore_Getopt_Desc * desc, - char *metavar, int *metavarlen, - int maxsize) -{ - if (desc->metavar) { - const char *txt = gettext(desc->metavar); - *metavarlen = strlen(txt); - if (*metavarlen > maxsize - 1) - *metavarlen = maxsize - 1; - - memcpy(metavar, txt, *metavarlen); - metavar[*metavarlen] = '\0'; - } else if (desc->longname) { - int i; - - *metavarlen = strlen(desc->longname); - if (*metavarlen > maxsize - 1) - *metavarlen = maxsize - 1; - - for (i = 0; i < *metavarlen; i++) - metavar[i] = toupper(desc->longname[i]); - metavar[i] = '\0'; - } -} - -static int -_ecore_getopt_help_desc_show_arg(FILE * fp, - Ecore_Getopt_Desc_Arg_Requirement - requirement, const char *metavar, - int metavarlen) -{ - int used; - - if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO) - return 0; - - used = 0; - - if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL) { - fputc('[', fp); - used++; - } - - if (requirement != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO) { - fputc('=', fp); - fputs(metavar, fp); - used += metavarlen + 1; - } - - if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL) { - fputc(']', fp); - used++; - } - - return used; -} - -static int -_ecore_getopt_help_desc_store(FILE * fp, const int base, const int total, - int used, const Ecore_Getopt_Desc * desc) -{ - const Ecore_Getopt_Desc_Store *store = &desc->action_param.store; - char buf[64]; - const char *str; - size_t len; - - fputc('\n', fp); - for (used = 0; used < base; used++) - fputc(' ', fp); - - switch (store->type) { - case ECORE_GETOPT_TYPE_STR: - str = "STR"; - len = sizeof("STR") - 1; - break; - case ECORE_GETOPT_TYPE_BOOL: - str = "BOOL"; - len = sizeof("BOOL") - 1; - break; - case ECORE_GETOPT_TYPE_SHORT: - str = "SHORT"; - len = sizeof("SHORT") - 1; - break; - case ECORE_GETOPT_TYPE_INT: - str = "INT"; - len = sizeof("INT") - 1; - break; - case ECORE_GETOPT_TYPE_LONG: - str = "LONG"; - len = sizeof("LONG") - 1; - break; - case ECORE_GETOPT_TYPE_USHORT: - str = "USHORT"; - len = sizeof("USHORT") - 1; - break; - case ECORE_GETOPT_TYPE_UINT: - str = "UINT"; - len = sizeof("UINT") - 1; - break; - case ECORE_GETOPT_TYPE_ULONG: - str = "ULONG"; - len = sizeof("ULONG") - 1; - break; - case ECORE_GETOPT_TYPE_DOUBLE: - str = "DOUBLE"; - len = sizeof("DOUBLE") - 1; - break; - default: - str = "???"; - len = sizeof("???") - 1; - } - - used = _ecore_getopt_help_line - (fp, base, total, used, _("Type: "), strlen(_("Type: "))); - used = _ecore_getopt_help_line(fp, base, total, used, str, len); - - if (store->arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES) - goto end; - - used = _ecore_getopt_help_line - (fp, base, total, used, ". ", sizeof(". ") - 1); - - switch (store->type) { - case ECORE_GETOPT_TYPE_STR: - str = store->def.strv; - len = str ? strlen(str) : 0; - break; - case ECORE_GETOPT_TYPE_BOOL: - str = store->def.boolv ? "true" : "false"; - len = strlen(str); - break; - case ECORE_GETOPT_TYPE_SHORT: - str = buf; - len = snprintf(buf, sizeof(buf), "%hd", store->def.shortv); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - break; - case ECORE_GETOPT_TYPE_INT: - str = buf; - len = snprintf(buf, sizeof(buf), "%d", store->def.intv); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - break; - case ECORE_GETOPT_TYPE_LONG: - str = buf; - len = snprintf(buf, sizeof(buf), "%ld", store->def.longv); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - break; - case ECORE_GETOPT_TYPE_USHORT: - str = buf; - len = - snprintf(buf, sizeof(buf), "%hu", store->def.ushortv); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - break; - case ECORE_GETOPT_TYPE_UINT: - str = buf; - len = snprintf(buf, sizeof(buf), "%u", store->def.uintv); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - break; - case ECORE_GETOPT_TYPE_ULONG: - str = buf; - len = snprintf(buf, sizeof(buf), "%lu", store->def.ulongv); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - break; - case ECORE_GETOPT_TYPE_DOUBLE: - str = buf; - len = snprintf(buf, sizeof(buf), "%f", store->def.doublev); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - break; - default: - str = "???"; - len = sizeof("???") - 1; - } - - used = _ecore_getopt_help_line - (fp, base, total, used, _("Default: "), - strlen(_("Default: "))); - used = _ecore_getopt_help_line(fp, base, total, used, str, len); - - end: - return _ecore_getopt_help_line(fp, base, total, used, ".", 1); -} - -static int -_ecore_getopt_help_desc_choices(FILE * fp, const int base, const int total, - int used, const Ecore_Getopt_Desc * desc) -{ - const char *const *itr; - const char sep[] = ", "; - const int seplen = sizeof(sep) - 1; - - if (used > 0) { - fputc('\n', fp); - used = 0; - } - for (; used < base; used++) - fputc(' ', fp); - - used = _ecore_getopt_help_line - (fp, base, total, used, _("Choices: "), - strlen(_("Choices: "))); - - for (itr = desc->action_param.choices; *itr; itr++) { - used = _ecore_getopt_help_line - (fp, base, total, used, *itr, strlen(*itr)); - if (itr[1]) - used = - _ecore_getopt_help_line(fp, base, total, used, - sep, seplen); - } - - return _ecore_getopt_help_line(fp, base, total, used, ".", 1); -} - -static void -_ecore_getopt_help_desc(FILE * fp, const Ecore_Getopt_Desc * desc) -{ - Ecore_Getopt_Desc_Arg_Requirement arg_req; - char metavar[32] = "ARG"; - int metavarlen = 3; - int used; - - arg_req = _ecore_getopt_desc_arg_requirement(desc); - if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO) - _ecore_getopt_help_desc_setup_metavar - (desc, metavar, &metavarlen, sizeof(metavar)); - - fputs(" ", fp); - used = 2; - - if (desc->shortname) { - fputc('-', fp); - fputc(desc->shortname, fp); - used += 2; - used += _ecore_getopt_help_desc_show_arg - (fp, arg_req, metavar, metavarlen); - } - - if (desc->shortname && desc->longname) { - fputs(", ", fp); - used += 2; - } - - if (desc->longname) { - int namelen = strlen(desc->longname); - - fputs("--", fp); - fputs(desc->longname, fp); - used += 2 + namelen; - used += _ecore_getopt_help_desc_show_arg - (fp, arg_req, metavar, metavarlen); - } - - if (!desc->help) - goto end; - - if (used + 3 >= helpcol) { - fputc('\n', fp); - used = 0; - } - - for (; used < helpcol; used++) - fputc(' ', fp); - - used = _ecore_getopt_help_line - (fp, helpcol, cols, used, desc->help, strlen(desc->help)); - - switch (desc->action) { - case ECORE_GETOPT_ACTION_STORE: - _ecore_getopt_help_desc_store(fp, helpcol, cols, used, - desc); - break; - case ECORE_GETOPT_ACTION_CHOICE: - _ecore_getopt_help_desc_choices(fp, helpcol, cols, used, - desc); - break; - default: - break; - } - - end: - fputc('\n', fp); -} - -static unsigned char -_ecore_getopt_desc_is_sentinel(const Ecore_Getopt_Desc * desc) -{ - return (desc->shortname == '\0') && (!desc->longname); -} - -static void -_ecore_getopt_help_options(FILE * fp, const Ecore_Getopt * parser) -{ - const Ecore_Getopt_Desc *desc; - - fputs(_("Options:\n"), fp); - - for (desc = parser->descs; !_ecore_getopt_desc_is_sentinel(desc); - desc++) - _ecore_getopt_help_desc(fp, desc); - - fputc('\n', fp); -} - -/** - * Show nicely formatted help message for the given parser. - * - * Message will be print to stderr. - */ -void ecore_getopt_help(FILE * fp, const Ecore_Getopt * parser) -{ - const char *var; - - if (!parser) - return; - - if (argc < 1) { - ecore_app_args_get(&argc, &argv); - if ((argc > 0) && (argv[0])) - prog = argv[0]; - else - prog = parser->prog; - } - - var = getenv("COLUMNS"); - if (var) { - cols = atoi(var); - if (cols < 20) - cols = 20; - - helpcol = cols / 3; - } - - _ecore_getopt_help_usage(fp, parser); - _ecore_getopt_help_description(fp, parser); - _ecore_getopt_help_options(fp, parser); -} - -static const Ecore_Getopt_Desc *_ecore_getopt_parse_find_long(const - Ecore_Getopt - * parser, - const char - *name) -{ - const Ecore_Getopt_Desc *desc = parser->descs; - const char *p = strchr(name, '='); - int len = 0; - - if (p) - len = p - name; - - for (; !_ecore_getopt_desc_is_sentinel(desc); desc++) { - if (!desc->longname) - continue; - - if (p) { - if ((strncmp(name, desc->longname, len) == 0) && - (desc->longname[len] == '\0')) - return desc; - } else { - if (strcmp(name, desc->longname) == 0) - return desc; - } - } - - return NULL; -} - -static const Ecore_Getopt_Desc *_ecore_getopt_parse_find_short(const - Ecore_Getopt - * parser, - char name) -{ - const Ecore_Getopt_Desc *desc = parser->descs; - for (; !_ecore_getopt_desc_is_sentinel(desc); desc++) - if (name == desc->shortname) - return desc; - return NULL; -} - -static int -_ecore_getopt_parse_find_nonargs_base(const Ecore_Getopt * parser, - int argc, char **argv) -{ - char **nonargs; - int src, dst, used, base; - - nonargs = alloca(sizeof(char *) * argc); - src = 1; - dst = 1; - used = 0; - base = 0; - while (src < argc) { - const Ecore_Getopt_Desc *desc; - Ecore_Getopt_Desc_Arg_Requirement arg_req; - char *arg = argv[src]; - - if (arg[0] != '-') - goto found_nonarg; - - if (arg[1] == '-') { - if (arg[2] == '\0') { /* explicit end of options, "--" */ - base = 1; - break; - } - desc = - _ecore_getopt_parse_find_long(parser, arg + 2); - } else - desc = - _ecore_getopt_parse_find_short(parser, arg[1]); - - if (!desc) { - if (arg[1] == '-') - fprintf(stderr, - _("ERROR: unknown option --%s.\n"), - arg + 2); - else - fprintf(stderr, - _("ERROR: unknown option -%c.\n"), - arg[1]); - if (parser->strict) { - memmove(argv + dst, nonargs, - used * sizeof(char *)); - return -1; - } else - goto found_nonarg; - } - - if (src != dst) - argv[dst] = argv[src]; - src++; - dst++; - - arg_req = _ecore_getopt_desc_arg_requirement(desc); - if (arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO) - continue; - - if (strchr(arg, '=')) - continue; - - if ((src >= argc) || (argv[src][0] == '-')) - continue; - - if (src != dst) - argv[dst] = argv[src]; - src++; - dst++; - continue; - - found_nonarg: - nonargs[used] = arg; - used++; - src++; - } - - if (!base) /* '--' not found */ - base = dst; - else { - base = dst; - if (src != dst) - argv[dst] = argv[src]; - dst++; - } - - memmove(argv + dst, nonargs, used * sizeof(char *)); - return base; -} - -static void -_ecore_getopt_desc_print_error(const Ecore_Getopt_Desc * desc, - const char *fmt, ...) -{ - va_list ap; - - fputs(_("ERROR: "), stderr); - - if (desc->shortname) { - fputc('-', stderr); - fputc(desc->shortname, stderr); - } - - if (desc->shortname && desc->longname) - fputs(", ", stderr); - - if (desc->longname) { - fputs("--", stderr); - fputs(desc->longname, stderr); - } - - fputs(": ", stderr); - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static unsigned char -_ecore_getopt_parse_bool(const char *str, unsigned char *v) -{ - if ((strcmp(str, "0") == 0) || - (strcasecmp(str, "f") == 0) || - (strcasecmp(str, "false") == 0) || - (strcasecmp(str, "no") == 0) || (strcasecmp(str, "off") == 0) - ) { - *v = 0; - return 1; - } else if ((strcmp(str, "1") == 0) || - (strcasecmp(str, "t") == 0) || - (strcasecmp(str, "true") == 0) || - (strcasecmp(str, "yes") == 0) || - (strcasecmp(str, "on") == 0) - ) { - *v = 1; - return 1; - } - - return 0; -} - -static unsigned char _ecore_getopt_parse_long(const char *str, long int *v) -{ - char *endptr = NULL; - *v = strtol(str, &endptr, 0); - return endptr > str; -} - -static unsigned char _ecore_getopt_parse_double(const char *str, double *v) -{ - char *endptr = NULL; - *v = strtod(str, &endptr); - return endptr > str; -} - -static unsigned char -_ecore_getopt_parse_store(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * value, const char *arg_val) -{ - const Ecore_Getopt_Desc_Store *store = &desc->action_param.store; - long int v; - double d; - unsigned char b; - - if (!value->ptrp) { - _ecore_getopt_desc_print_error(desc, - _ - ("value has no pointer set.\n")); - return 0; - } - - switch (store->arg_req) { - case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO: - goto use_optional; - case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL: - if (!arg_val) - goto use_optional; - case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES: - break; - } - - switch (store->type) { - case ECORE_GETOPT_TYPE_STR: - *value->strp = (char *) arg_val; - return 1; - case ECORE_GETOPT_TYPE_BOOL: - if (_ecore_getopt_parse_bool(arg_val, &b)) { - *value->boolp = b; - return 1; - } else { - _ecore_getopt_desc_print_error - (desc, _("unknown boolean value %s.\n"), - arg_val); - return 0; - } - case ECORE_GETOPT_TYPE_SHORT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->shortp = v; - return 1; - case ECORE_GETOPT_TYPE_INT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->intp = v; - return 1; - case ECORE_GETOPT_TYPE_LONG: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->longp = v; - return 1; - case ECORE_GETOPT_TYPE_USHORT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->ushortp = v; - return 1; - case ECORE_GETOPT_TYPE_UINT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->uintp = v; - return 1; - case ECORE_GETOPT_TYPE_ULONG: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->ulongp = v; - return 1; - case ECORE_GETOPT_TYPE_DOUBLE: - if (!_ecore_getopt_parse_double(arg_val, &d)) - goto error; - *value->doublep = d; - break; - } - - return 1; - - error: - _ecore_getopt_desc_print_error - (desc, _("invalid number format %s\n"), arg_val); - return 0; - - use_optional: - switch (store->type) { - case ECORE_GETOPT_TYPE_STR: - *value->strp = (char *) store->def.strv; - break; - case ECORE_GETOPT_TYPE_BOOL: - *value->boolp = store->def.boolv; - break; - case ECORE_GETOPT_TYPE_SHORT: - *value->shortp = store->def.shortv; - break; - case ECORE_GETOPT_TYPE_INT: - *value->intp = store->def.intv; - break; - case ECORE_GETOPT_TYPE_LONG: - *value->longp = store->def.longv; - break; - case ECORE_GETOPT_TYPE_USHORT: - *value->ushortp = store->def.ushortv; - break; - case ECORE_GETOPT_TYPE_UINT: - *value->uintp = store->def.uintv; - break; - case ECORE_GETOPT_TYPE_ULONG: - *value->ulongp = store->def.ulongv; - break; - case ECORE_GETOPT_TYPE_DOUBLE: - *value->doublep = store->def.doublev; - break; - } - - return 1; -} - -static unsigned char -_ecore_getopt_parse_store_const(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (!val->ptrp) { - _ecore_getopt_desc_print_error(desc, - _ - ("value has no pointer set.\n")); - return 0; - } - - *val->ptrp = (void *) desc->action_param.store_const; - return 1; -} - -static unsigned char -_ecore_getopt_parse_store_true(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (!val->boolp) { - _ecore_getopt_desc_print_error(desc, - _ - ("value has no pointer set.\n")); - return 0; - } - *val->boolp = 1; - return 1; -} - -static unsigned char -_ecore_getopt_parse_store_false(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (!val->boolp) { - _ecore_getopt_desc_print_error(desc, - _ - ("value has no pointer set.\n")); - return 0; - } - *val->boolp = 0; - return 1; -} - -static unsigned char -_ecore_getopt_parse_choice(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, const char *arg_val) -{ - const char *const *pchoice; - - if (!val->strp) { - _ecore_getopt_desc_print_error(desc, - _ - ("value has no pointer set.\n")); - return 0; - } - - pchoice = desc->action_param.choices; - for (; *pchoice; pchoice++) - if (strcmp(*pchoice, arg_val) == 0) { - *val->strp = (char *) *pchoice; - return 1; - } - - _ecore_getopt_desc_print_error - (desc, _("invalid choice \"%s\". Valid values are: "), - arg_val); - - pchoice = desc->action_param.choices; - for (; *pchoice; pchoice++) { - fputs(*pchoice, stderr); - if (pchoice[1]) - fputs(", ", stderr); - } - - fputs(".\n", stderr); - return 0; -} - -static unsigned char -_ecore_getopt_parse_append(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, const char *arg_val) -{ - void *data; - long int v; - double d; - unsigned char b; - - if (!arg_val) { - _ecore_getopt_desc_print_error - (desc, _("missing parameter to append.\n")); - return 0; - } - - if (!val->listp) { - _ecore_getopt_desc_print_error(desc, - _ - ("value has no pointer set.\n")); - return 0; - } - - switch (desc->action_param.append_type) { - case ECORE_GETOPT_TYPE_STR: - data = strdup(arg_val); - break; - case ECORE_GETOPT_TYPE_BOOL: - { - if (_ecore_getopt_parse_bool(arg_val, &b)) { - data = malloc(sizeof(unsigned char)); - if (data) - *(unsigned char *) data = b; - } else { - _ecore_getopt_desc_print_error - (desc, - _("unknown boolean value %s.\n"), - arg_val); - return 0; - } - } - break; - case ECORE_GETOPT_TYPE_SHORT: - { - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - data = malloc(sizeof(short)); - if (data) - *(short *) data = (short) v; - } - break; - case ECORE_GETOPT_TYPE_INT: - { - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - data = malloc(sizeof(int)); - if (data) - *(int *) data = (int) v; - } - break; - case ECORE_GETOPT_TYPE_LONG: - { - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - data = malloc(sizeof(long)); - if (data) - *(long *) data = v; - } - break; - case ECORE_GETOPT_TYPE_USHORT: - { - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - data = malloc(sizeof(unsigned short)); - if (data) - *(unsigned short *) data = - (unsigned short) v; - } - break; - case ECORE_GETOPT_TYPE_UINT: - { - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - data = malloc(sizeof(unsigned int)); - if (data) - *(unsigned int *) data = (unsigned int) v; - } - break; - case ECORE_GETOPT_TYPE_ULONG: - { - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - data = malloc(sizeof(unsigned long)); - if (data) - *(unsigned long *) data = v; - } - break; - case ECORE_GETOPT_TYPE_DOUBLE: - { - if (!_ecore_getopt_parse_double(arg_val, &d)) - goto error; - data = malloc(sizeof(double)); - if (data) - *(double *) data = d; - } - break; - default: - { - _ecore_getopt_desc_print_error(desc, - _ - ("could not parse value.\n")); - return 0; - } - } - - *val->listp = eina_list_append(*val->listp, data); - return 1; - - error: - _ecore_getopt_desc_print_error - (desc, _("invalid number format %s\n"), arg_val); - return 0; -} - -static unsigned char -_ecore_getopt_parse_count(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (!val->intp) { - _ecore_getopt_desc_print_error(desc, - _ - ("value has no pointer set.\n")); - return 0; - } - - (*val->intp)++; - return 1; -} - -static unsigned char -_ecore_getopt_parse_callback(const Ecore_Getopt * parser, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, const char *arg_val) -{ - const Ecore_Getopt_Desc_Callback *cb = - &desc->action_param.callback; - - switch (cb->arg_req) { - case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO: - arg_val = cb->def; - break; - case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL: - if (!arg_val) - arg_val = cb->def; - break; - case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES: - break; - } - - if (cb->arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO) { - if ((!arg_val) || (arg_val[0] == '\0')) { - _ecore_getopt_desc_print_error(desc, - _ - ("missing parameter.\n")); - return 0; - } - - if (!val->ptrp) { - _ecore_getopt_desc_print_error - (desc, _("value has no pointer set.\n")); - return 0; - } - } - - if (!cb->func) { - _ecore_getopt_desc_print_error(desc, - _ - ("missing callback function!\n")); - return 0; - } - - return cb->func(parser, desc, arg_val, (void *) cb->data, val); -} - -static unsigned char -_ecore_getopt_parse_help(const Ecore_Getopt * parser, - const Ecore_Getopt_Desc * desc __UNUSED__, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (val->boolp) - (*val->boolp) = 1; - ecore_getopt_help(stdout, parser); - return 1; -} - -static unsigned char -_ecore_getopt_parse_version(const Ecore_Getopt * parser, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (val->boolp) - (*val->boolp) = 1; - if (!parser->version) { - _ecore_getopt_desc_print_error(desc, - _ - ("no version was defined.\n")); - return 0; - } - _ecore_getopt_version(stdout, parser); - return 1; -} - -static unsigned char -_ecore_getopt_parse_copyright(const Ecore_Getopt * parser, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (val->boolp) - (*val->boolp) = 1; - if (!parser->copyright) { - _ecore_getopt_desc_print_error(desc, - _ - ("no copyright was defined.\n")); - return 0; - } - _ecore_getopt_copyright(stdout, parser); - return 1; -} - -static unsigned char -_ecore_getopt_parse_license(const Ecore_Getopt * parser, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * val, - const char *arg_val __UNUSED__) -{ - if (val->boolp) - (*val->boolp) = 1; - if (!parser->license) { - _ecore_getopt_desc_print_error(desc, - _ - ("no license was defined.\n")); - return 0; - } - _ecore_getopt_license(stdout, parser); - return 1; -} - -static unsigned char -_ecore_getopt_desc_handle(const Ecore_Getopt * parser, - const Ecore_Getopt_Desc * desc, - Ecore_Getopt_Value * value, const char *arg_val) -{ - switch (desc->action) { - case ECORE_GETOPT_ACTION_STORE: - return _ecore_getopt_parse_store(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_STORE_CONST: - return _ecore_getopt_parse_store_const(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_STORE_TRUE: - return _ecore_getopt_parse_store_true(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_STORE_FALSE: - return _ecore_getopt_parse_store_false(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_CHOICE: - return _ecore_getopt_parse_choice(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_APPEND: - return _ecore_getopt_parse_append(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_COUNT: - return _ecore_getopt_parse_count(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_CALLBACK: - return _ecore_getopt_parse_callback(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_HELP: - return _ecore_getopt_parse_help(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_VERSION: - return _ecore_getopt_parse_version(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_COPYRIGHT: - return _ecore_getopt_parse_copyright(parser, desc, value, - arg_val); - case ECORE_GETOPT_ACTION_LICENSE: - return _ecore_getopt_parse_license(parser, desc, value, - arg_val); - default: - return 0; - } -} - -static unsigned char -_ecore_getopt_parse_arg_long(const Ecore_Getopt * parser, - Ecore_Getopt_Value * values, - int argc __UNUSED__, char **argv, int *idx, - int *nonargs, const char *arg) -{ - const Ecore_Getopt_Desc *desc; - Ecore_Getopt_Desc_Arg_Requirement arg_req; - const char *arg_val; - int desc_idx; - Ecore_Getopt_Value *value; - unsigned char ret; - - desc = _ecore_getopt_parse_find_long(parser, arg); - if (!desc) { - fprintf(stderr, - _("ERROR: unknown option --%s, ignored.\n"), arg); - if (parser->strict) - return 0; - - (*idx)++; - return 1; - } - - (*idx)++; - - arg_req = _ecore_getopt_desc_arg_requirement(desc); - if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO) { - arg_val = strchr(arg, '='); - if (arg_val) - arg_val++; - else { - if ((*idx < *nonargs) && (argv[*idx][0] != '-')) { - arg_val = argv[*idx]; - (*idx)++; - } else - arg_val = NULL; - } - - if (arg_val && arg_val[0] == '\0') - arg_val = NULL; - - if ((!arg_val) - && (arg_req == - ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES)) { - fprintf(stderr, - _ - ("ERROR: option --%s requires an argument!\n"), - arg); - if (parser->strict) - return 0; - return 1; - } - } else - arg_val = NULL; - - desc_idx = desc - parser->descs; - value = values + desc_idx; - ret = _ecore_getopt_desc_handle(parser, desc, value, arg_val); - if ((!ret) && parser->strict) - return 0; - - return 1; -} - -static unsigned char -_ecore_getopt_parse_arg_short(const Ecore_Getopt * parser, - Ecore_Getopt_Value * values, - int argc __UNUSED__, char **argv, int *idx, - int *nonargs, const char *arg) -{ - int run = 1; - while (run && (arg[0] != '\0')) { - int opt = arg[0]; - const Ecore_Getopt_Desc *desc; - Ecore_Getopt_Desc_Arg_Requirement arg_req; - const char *arg_val; - int desc_idx; - Ecore_Getopt_Value *value; - unsigned char ret; - - desc = _ecore_getopt_parse_find_short(parser, arg[0]); - if (!desc) { - fprintf - (stderr, - _("ERROR: unknown option -%c, ignored.\n"), - arg[0]); - if (parser->strict) - return 0; - - arg++; - continue; - } - - arg++; - - arg_req = _ecore_getopt_desc_arg_requirement(desc); - if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO) { - (*idx)++; - run = 0; - - if (arg[0] == '=') - arg_val = arg + 1; - else if (arg[0] != '\0') - arg_val = arg; - else { - if ((*idx < *nonargs) - && (argv[*idx][0] != '-')) { - arg_val = argv[*idx]; - (*idx)++; - } else - arg_val = NULL; - } - - if (arg_val && arg_val[0] == '\0') - arg_val = NULL; - - if ((!arg_val) && - (arg_req == - ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES)) { - fprintf(stderr, - _ - ("ERROR: option -%c requires an argument!\n"), - opt); - if (parser->strict) - return 0; - return 1; - } - } else - arg_val = NULL; - - desc_idx = desc - parser->descs; - value = values + desc_idx; - ret = - _ecore_getopt_desc_handle(parser, desc, value, - arg_val); - if ((!ret) && parser->strict) - return 0; - } - - if (run) - (*idx)++; - - return 1; -} - -static unsigned char -_ecore_getopt_parse_arg(const Ecore_Getopt * parser, - Ecore_Getopt_Value * values, int argc, char **argv, - int *idx, int *nonargs) -{ - char *arg = argv[*idx]; - - if (arg[0] != '-') { - char **dst, **src, **src_end; - - dst = argv + *idx; - src = dst + 1; - src_end = src + *nonargs - *idx - 1; - - for (; src < src_end; src++, dst++) - *dst = *src; - - *dst = arg; - (*nonargs)--; - return 1; - } - - if (arg[1] == '-') - return _ecore_getopt_parse_arg_long - (parser, values, argc, argv, idx, nonargs, arg + 2); - else - return _ecore_getopt_parse_arg_short - (parser, values, argc, argv, idx, nonargs, arg + 1); -} - -static const Ecore_Getopt_Desc *_ecore_getopt_parse_find_short_other(const - Ecore_Getopt - * - parser, - const - Ecore_Getopt_Desc - * - orig) -{ - const Ecore_Getopt_Desc *desc = parser->descs; - const char c = orig->shortname; - - for (; !_ecore_getopt_desc_is_sentinel(desc); desc++) { - if (desc == orig) - return NULL; - - if (c == desc->shortname) - return desc; - } - - return NULL; -} - -static const Ecore_Getopt_Desc *_ecore_getopt_parse_find_long_other(const - Ecore_Getopt - * - parser, - const - Ecore_Getopt_Desc - * orig) -{ - const Ecore_Getopt_Desc *desc = parser->descs; - const char *name = orig->longname; - - for (; !_ecore_getopt_desc_is_sentinel(desc); desc++) { - if (desc == orig) - return NULL; - - if (desc->longname && (strcmp(name, desc->longname) == 0)) - return desc; - } - - return NULL; -} - -/** - * Check parser for duplicate entries, print them out. - * - * @return 1 if there are duplicates, 0 otherwise. - */ -unsigned char -ecore_getopt_parser_has_duplicates(const Ecore_Getopt * parser) -{ - const Ecore_Getopt_Desc *desc = parser->descs; - for (; !_ecore_getopt_desc_is_sentinel(desc); desc++) { - if (desc->shortname) { - const Ecore_Getopt_Desc *other; - other = - _ecore_getopt_parse_find_short_other(parser, - desc); - if (other) { - _ecore_getopt_desc_print_error - (desc, - "short name -%c already exists.", - desc->shortname); - - if (other->longname) - fprintf(stderr, - " Other is --%s.\n", - other->longname); - else - fputc('\n', stderr); - return 1; - } - } - - if (desc->longname) { - const Ecore_Getopt_Desc *other; - other = - _ecore_getopt_parse_find_long_other(parser, - desc); - if (other) { - _ecore_getopt_desc_print_error - (desc, - "long name --%s already exists.", - desc->longname); - - if (other->shortname) - fprintf(stderr, " Other is -%c.\n", - other->shortname); - else - fputc('\n', stderr); - return 1; - } - } - } - return 0; -} - -static const Ecore_Getopt_Desc *_ecore_getopt_find_help(const Ecore_Getopt - * parser) -{ - const Ecore_Getopt_Desc *desc = parser->descs; - for (; !_ecore_getopt_desc_is_sentinel(desc); desc++) - if (desc->action == ECORE_GETOPT_ACTION_HELP) - return desc; - return NULL; -} - -/** - * Parse command line parameters. - * - * Walks the command line parameters and parse them based on @a parser - * description, doing actions based on @c parser->descs->action, like - * showing help text, license, copyright, storing values in values and - * so on. - * - * It is expected that values is of the same size than @c parser->descs, - * options that do not need a value it will be left untouched. - * - * All values are expected to be initialized before use. Options with - * action @c ECORE_GETOPT_ACTION_STORE and non required arguments - * (others than @c ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES), are expected - * to provide a value in @c def to be used. - * - * The following actions will store 1 on value as a boolean - * (@c value->boolp) if it's not NULL to indicate these actions were executed: - * - @c ECORE_GETOPT_ACTION_HELP - * - @c ECORE_GETOPT_ACTION_VERSION - * - @c ECORE_GETOPT_ACTION_COPYRIGHT - * - @c ECORE_GETOPT_ACTION_LICENSE - * - * Just @c ECORE_GETOPT_ACTION_APPEND will allocate memory and thus - * need to be freed. For consistency between all of appended subtypes, - * @c eina_list->data will contain an allocated memory with the value, - * that is, for @c ECORE_GETOPT_TYPE_STR it will contain a copy of the - * argument, @c ECORE_GETOPT_TYPE_INT a pointer to an allocated - * integer and so on. - * - * If parser is in strict mode (see @c Ecore_Getopt->strict), then any - * error will abort parsing and -1 is returned. Otherwise it will try - * to continue as far as possible. - * - * This function may reorder @a argv elements. - * - * Translation of help strings (description), metavar, usage, license - * and copyright may be translated, standard/global gettext() call - * will be applied on them if ecore was compiled with such support. - * - * @param parser description of how to work. - * @param value where to store values, it is assumed that this is a vector - * of the same size as @c parser->descs. Values should be previously - * initialized. - * @param argc how many elements in @a argv. If not provided it will be - * retrieved with ecore_app_args_get(). - * @param argv command line parameters. - * - * @return index of first non-option parameter or -1 on error. - */ -int -ecore_getopt_parse(const Ecore_Getopt * parser, - Ecore_Getopt_Value * values, int argc, char **argv) -{ - int i, nonargs; - - if (!parser) { - fputs(_("ERROR: no parser provided.\n"), stderr); - return -1; - } - if (!values) { - fputs(_("ERROR: no values provided.\n"), stderr); - return -1; - } - - if ((argc < 1) || (!argv)) - ecore_app_args_get(&argc, &argv); - - if (argc < 1) { - fputs(_("ERROR: no arguments provided.\n"), stderr); - return -1; - } - - if (argv[0]) - prog = argv[0]; - else - prog = parser->prog; - - nonargs = - _ecore_getopt_parse_find_nonargs_base(parser, argc, argv); - if (nonargs < 0) - goto error; - - if (nonargs > argc) - nonargs = argc; - - i = 1; - while (i < nonargs) - if (!_ecore_getopt_parse_arg - (parser, values, argc, argv, &i, &nonargs)) - goto error; - - return nonargs; - - error: - { - const Ecore_Getopt_Desc *help; - fputs(_("ERROR: invalid options found."), stderr); - - help = _ecore_getopt_find_help(parser); - if (!help) - fputc('\n', stderr); - else if (help->longname) - fprintf(stderr, _(" See --%s.\n"), help->longname); - else - fprintf(stderr, _(" See -%c.\n"), help->shortname); - } - - return -1; -} - -/** - * Utility to free list and nodes allocated by @a ECORE_GETOPT_ACTION_APPEND. - * - * @param list pointer to list to be freed. - * @return always NULL, so you can easily make your list head NULL. - */ -Eina_List *ecore_getopt_list_free(Eina_List * list) -{ - void *data; - - EINA_LIST_FREE(list, data) - free(data); - return NULL; -} - -/** - * Helper ecore_getopt callback to parse geometry (x:y:w:h). - * - * Storage must be a pointer to @c Eina_Rectangle and will be used to - * store the four values passed in the given string. - * - * @c callback_data value is ignored, you can safely use @c NULL. - */ -unsigned char -ecore_getopt_callback_geometry_parse(const Ecore_Getopt * - parser __UNUSED__, - const Ecore_Getopt_Desc * - desc __UNUSED__, const char *str, - void *data __UNUSED__, - Ecore_Getopt_Value * storage) -{ - Eina_Rectangle *v = (Eina_Rectangle *) storage->ptrp; - - if (sscanf(str, "%d:%d:%d:%d", &v->x, &v->y, &v->w, &v->h) != 4) { - fprintf(stderr, - _("ERROR: incorrect geometry value '%s'\n"), str); - return 0; - } - - return 1; -} - -/** - * Helper ecore_getopt callback to parse geometry size (WxH). - * - * Storage must be a pointer to @c Eina_Rectangle and will be used to - * store the two values passed in the given string and 0 in the x and y - * fields. - * - * @c callback_data value is ignored, you can safely use @c NULL. - */ -unsigned char -ecore_getopt_callback_size_parse(const Ecore_Getopt * parser __UNUSED__, - const Ecore_Getopt_Desc * desc __UNUSED__, - const char *str, void *data __UNUSED__, - Ecore_Getopt_Value * storage) -{ - Eina_Rectangle *v = (Eina_Rectangle *) storage->ptrp; - - if (sscanf(str, "%dx%d", &v->w, &v->h) != 2) { - fprintf(stderr, _("ERROR: incorrect size value '%s'\n"), - str); - return 0; - } - v->x = 0; - v->y = 0; - - return 1; -} diff --git a/tests/suite/ecore/src/lib/ecore_glib.c b/tests/suite/ecore/src/lib/ecore_glib.c deleted file mode 100644 index d986d221cf..0000000000 --- a/tests/suite/ecore/src/lib/ecore_glib.c +++ /dev/null @@ -1,290 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> - -#include "Ecore.h" -#include "ecore_private.h" - -#ifdef HAVE_GLIB -#include <glib.h> - -static Eina_Bool _ecore_glib_active = EINA_FALSE; -static Ecore_Select_Function _ecore_glib_select_original; -static GCond *_ecore_glib_cond = NULL; -static GPollFD *_ecore_glib_fds = NULL; -static size_t _ecore_glib_fds_size = 0; -static const size_t ECORE_GLIB_FDS_INITIAL = 128; -static const size_t ECORE_GLIB_FDS_STEP = 8; -static const size_t ECORE_GLIB_FDS_MAX_FREE = 256; - -static Eina_Bool _ecore_glib_fds_resize(size_t size) -{ - void *tmp = realloc(_ecore_glib_fds, sizeof(GPollFD) * size); - - if (!tmp) { - ERR("Could not realloc from %zu to %zu buckets.", - _ecore_glib_fds_size, size); - return EINA_FALSE; - } - - _ecore_glib_fds = tmp; - _ecore_glib_fds_size = size; - return EINA_TRUE; -} - -static int -_ecore_glib_context_query(GMainContext * ctx, int priority, int *p_timer) -{ - int reqfds; - - if (_ecore_glib_fds_size == 0) { - if (!_ecore_glib_fds_resize(ECORE_GLIB_FDS_INITIAL)) - return -1; - } - - while (1) { - size_t size; - - reqfds = g_main_context_query - (ctx, priority, p_timer, _ecore_glib_fds, - _ecore_glib_fds_size); - if (reqfds <= (int) _ecore_glib_fds_size) - break; - - size = - (1 + - reqfds / ECORE_GLIB_FDS_STEP) * ECORE_GLIB_FDS_STEP; - if (!_ecore_glib_fds_resize(size)) - return -1; - } - - if (reqfds + ECORE_GLIB_FDS_MAX_FREE < _ecore_glib_fds_size) { - size_t size; - - size = - (1 + - reqfds / ECORE_GLIB_FDS_MAX_FREE) * - ECORE_GLIB_FDS_MAX_FREE; - _ecore_glib_fds_resize(size); - } - - return reqfds; -} - -static int -_ecore_glib_context_poll_from(const GPollFD * pfds, int count, - fd_set * rfds, fd_set * wfds, fd_set * efds) -{ - const GPollFD *itr = pfds, *itr_end = pfds + count; - int glib_fds = -1; - - for (; itr < itr_end; itr++) { - if (glib_fds < itr->fd) - glib_fds = itr->fd; - - if (itr->events & G_IO_IN) - FD_SET(itr->fd, rfds); - if (itr->events & G_IO_OUT) - FD_SET(itr->fd, wfds); - if (itr->events & (G_IO_HUP | G_IO_ERR)) - FD_SET(itr->fd, efds); - } - - return glib_fds + 1; -} - -static int -_ecore_glib_context_poll_to(GPollFD * pfds, int count, const fd_set * rfds, - const fd_set * wfds, const fd_set * efds, - int ready) -{ - GPollFD *itr = pfds, *itr_end = pfds + count; - - for (; itr < itr_end && ready > 0; itr++) { - itr->revents = 0; - if (FD_ISSET(itr->fd, rfds)) { - itr->revents |= G_IO_IN; - ready--; - } - if (FD_ISSET(itr->fd, wfds)) { - itr->revents |= G_IO_OUT; - ready--; - } - if (FD_ISSET(itr->fd, efds)) { - itr->revents |= G_IO_ERR; - ready--; - } - } - return ready; -} - -static int -_ecore_glib_select__locked(GMainContext * ctx, int ecore_fds, - fd_set * rfds, fd_set * wfds, fd_set * efds, - struct timeval *ecore_timeout) -{ - int priority, maxfds, glib_fds, reqfds, reqtimeout, ret; - struct timeval *timeout, glib_timeout; - - g_main_context_prepare(ctx, &priority); - reqfds = _ecore_glib_context_query(ctx, priority, &reqtimeout); - if (reqfds < 0) - goto error; - - glib_fds = _ecore_glib_context_poll_from - (_ecore_glib_fds, reqfds, rfds, wfds, efds); - - if (reqtimeout == -1) - timeout = ecore_timeout; - else { - glib_timeout.tv_sec = reqtimeout / 1000; - glib_timeout.tv_usec = (reqtimeout % 1000) * 1000; - - if (!ecore_timeout - || timercmp(ecore_timeout, &glib_timeout, >)) - timeout = &glib_timeout; - else - timeout = ecore_timeout; - } - - maxfds = (ecore_fds >= glib_fds) ? ecore_fds : glib_fds; - ret = - _ecore_glib_select_original(maxfds, rfds, wfds, efds, timeout); - - ret = _ecore_glib_context_poll_to - (_ecore_glib_fds, reqfds, rfds, wfds, efds, ret); - - if (g_main_context_check(ctx, priority, _ecore_glib_fds, reqfds)) - g_main_context_dispatch(ctx); - - return ret; - - error: - return _ecore_glib_select_original - (ecore_fds, rfds, wfds, efds, ecore_timeout); -} - -static int -_ecore_glib_select(int ecore_fds, fd_set * rfds, fd_set * wfds, - fd_set * efds, struct timeval *ecore_timeout) -{ - GStaticMutex lock = G_STATIC_MUTEX_INIT; - GMutex *mutex = g_static_mutex_get_mutex(&lock); - GMainContext *ctx = g_main_context_default(); - int ret; - - if (g_main_context_acquire(ctx)) - g_mutex_lock(mutex); - else { - if (!_ecore_glib_cond) - _ecore_glib_cond = g_cond_new(); - - while (!g_main_context_wait(ctx, _ecore_glib_cond, mutex)) - g_thread_yield(); - } - - ret = _ecore_glib_select__locked - (ctx, ecore_fds, rfds, wfds, efds, ecore_timeout); - - g_mutex_unlock(mutex); - g_main_context_release(ctx); - - return ret; -} -#endif - -void _ecore_glib_init(void) -{ -} - -void _ecore_glib_shutdown(void) -{ -#ifdef HAVE_GLIB - if (!_ecore_glib_active) - return; - _ecore_glib_active = EINA_FALSE; - - if (ecore_main_loop_select_func_get() == _ecore_glib_select) - ecore_main_loop_select_func_set - (_ecore_glib_select_original); - - if (_ecore_glib_fds) { - free(_ecore_glib_fds); - _ecore_glib_fds = NULL; - } - _ecore_glib_fds_size = 0; - - if (_ecore_glib_cond) { - g_cond_free(_ecore_glib_cond); - _ecore_glib_cond = NULL; - } -#endif -} - -/** - * Request ecore to integrate GLib's main loop. - * - * This will add a small overhead during every main loop interaction - * by checking glib's default main context (used by its main loop). If - * it have events to be checked (timers, file descriptors or idlers), - * then these will be polled alongside with Ecore's own events, then - * dispatched before Ecore's. This is done by calling - * ecore_main_loop_select_func_set(). - * - * This will cooperate with previously set - * ecore_main_loop_select_func_set() by calling the old - * function. Similarly, if you want to override - * ecore_main_loop_select_func_set() after main loop is integrated, - * call the new select function set by this call (get it by calling - * ecore_main_loop_select_func_get() right after - * ecore_main_loop_glib_integrate()). - * - * This is useful to use GMainLoop libraries, like GTK, GUPnP, - * LibSoup, GConf and more. Adobe Flash plugin and other plugins - * systems depend on this as well. - * - * Once initialized/integrated, it will be valid until Ecore is - * completely shut down. - * - * @note this is only available if Ecore was compiled with GLib support. - * - * @return @c EINA_TRUE on success of @c EINA_FALSE if it failed, - * likely no GLib support in Ecore. - */ -EAPI Eina_Bool ecore_main_loop_glib_integrate(void) -{ -#ifdef HAVE_GLIB - void *func; - - if (_ecore_glib_active) - return EINA_TRUE; - func = ecore_main_loop_select_func_get(); - if (func == _ecore_glib_select) - return EINA_TRUE; - _ecore_glib_select_original = func; - ecore_main_loop_select_func_set(_ecore_glib_select); - _ecore_glib_active = EINA_TRUE; - return EINA_TRUE; -#else - fputs("ERROR: no glib support in ecore.\n", stderr); - return EINA_FALSE; -#endif -} - -Eina_Bool _ecore_glib_always_integrate = 1; - -/** - * Disable always integrating glib - * - * If ecore is compiled with --enable-glib-integration-always (to always - * call ecore_main_loop_glib_integrate() when ecore_init() is called), then - * calling this before calling ecore_init() will disable the integration. - * This is for apps that explicitly do not want this to happen for whatever - * reasons they may have. - */ -EAPI void ecore_main_loop_glib_always_integrate_disable(void) -{ - _ecore_glib_always_integrate = 0; -} diff --git a/tests/suite/ecore/src/lib/ecore_idle_enterer.c b/tests/suite/ecore/src/lib/ecore_idle_enterer.c deleted file mode 100644 index 62c340f109..0000000000 --- a/tests/suite/ecore/src/lib/ecore_idle_enterer.c +++ /dev/null @@ -1,178 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include "Ecore.h" -#include "ecore_private.h" - - -struct _Ecore_Idle_Enterer { - EINA_INLIST; - ECORE_MAGIC; - Ecore_Task_Cb func; - void *data; - int references; - Eina_Bool delete_me:1; -}; - - -static Ecore_Idle_Enterer *idle_enterers = NULL; -static Ecore_Idle_Enterer *idle_enterer_current = NULL; -static int idle_enterers_delete_me = 0; - -/** - * Add an idle enterer handler. - * @param func The function to call when entering an idle state. - * @param data The data to be passed to the @p func call - * @return A handle to the idle enterer callback if successful. Otherwise, - * NULL is returned. - * @ingroup Idle_Group - */ -EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Idle_Enterer *ie; - - if (!func) - return NULL; - ie = calloc(1, sizeof(Ecore_Idle_Enterer)); - if (!ie) - return NULL; - ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER); - ie->func = func; - ie->data = (void *) data; - idle_enterers = - (Ecore_Idle_Enterer *) - eina_inlist_append(EINA_INLIST_GET(idle_enterers), - EINA_INLIST_GET(ie)); - return ie; -} - -/** - * Add an idle enterer handler at the start of the list so it gets called earlier than others. - * @param func The function to call when entering an idle state. - * @param data The data to be passed to the @p func call - * @return A handle to the idle enterer callback if successful. Otherwise, - * NULL is returned. - * @ingroup Idle_Group - */ -EAPI Ecore_Idle_Enterer *ecore_idle_enterer_before_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Idle_Enterer *ie; - - if (!func) - return NULL; - ie = calloc(1, sizeof(Ecore_Idle_Enterer)); - if (!ie) - return NULL; - ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER); - ie->func = func; - ie->data = (void *) data; - idle_enterers = - (Ecore_Idle_Enterer *) - eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), - EINA_INLIST_GET(ie)); - return ie; -} - -/** - * Delete an idle enterer callback. - * @param idle_enterer The idle enterer to delete - * @return The data pointer passed to the idler enterer callback on success. - * NULL otherwise. - * @ingroup Idle_Group - */ -EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer * idle_enterer) -{ - if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER)) { - ECORE_MAGIC_FAIL(idle_enterer, ECORE_MAGIC_IDLE_ENTERER, - "ecore_idle_enterer_del"); - return NULL; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL); - idle_enterer->delete_me = 1; - idle_enterers_delete_me = 1; - return idle_enterer->data; -} - -void _ecore_idle_enterer_shutdown(void) -{ - Ecore_Idle_Enterer *ie; - while ((ie = idle_enterers)) { - idle_enterers = - (Ecore_Idle_Enterer *) - eina_inlist_remove(EINA_INLIST_GET(idle_enterers), - EINA_INLIST_GET(idle_enterers)); - ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); - free(ie); - } - idle_enterers_delete_me = 0; - idle_enterer_current = NULL; -} - -void _ecore_idle_enterer_call(void) -{ - if (!idle_enterer_current) { - /* regular main loop, start from head */ - idle_enterer_current = idle_enterers; - } else { - /* recursive main loop, continue from where we were */ - idle_enterer_current = - (Ecore_Idle_Enterer *) - EINA_INLIST_GET(idle_enterer_current)->next; - } - - while (idle_enterer_current) { - Ecore_Idle_Enterer *ie = - (Ecore_Idle_Enterer *) idle_enterer_current; - if (!ie->delete_me) { - ie->references++; - if (!ie->func(ie->data)) { - if (!ie->delete_me) - ecore_idle_enterer_del(ie); - } - ie->references--; - } - if (idle_enterer_current) /* may have changed in recursive main loops */ - idle_enterer_current = - (Ecore_Idle_Enterer *) - EINA_INLIST_GET(idle_enterer_current)->next; - } - if (idle_enterers_delete_me) { - Ecore_Idle_Enterer *l; - int deleted_idler_enterers_in_use = 0; - - for (l = idle_enterers; l;) { - Ecore_Idle_Enterer *ie = l; - l = (Ecore_Idle_Enterer *) EINA_INLIST_GET(l)-> - next; - if (ie->delete_me) { - if (ie->references) { - deleted_idler_enterers_in_use++; - continue; - } - - idle_enterers = - (Ecore_Idle_Enterer *) - eina_inlist_remove(EINA_INLIST_GET - (idle_enterers), - EINA_INLIST_GET - (ie)); - ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); - free(ie); - } - } - if (!deleted_idler_enterers_in_use) - idle_enterers_delete_me = 0; - } -} - -int _ecore_idle_enterer_exist(void) -{ - if (idle_enterers) - return 1; - return 0; -} diff --git a/tests/suite/ecore/src/lib/ecore_idle_exiter.c b/tests/suite/ecore/src/lib/ecore_idle_exiter.c deleted file mode 100644 index 0e9dbaf622..0000000000 --- a/tests/suite/ecore/src/lib/ecore_idle_exiter.c +++ /dev/null @@ -1,149 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include "Ecore.h" -#include "ecore_private.h" - - -struct _Ecore_Idle_Exiter { - EINA_INLIST; - ECORE_MAGIC; - Ecore_Task_Cb func; - void *data; - int references; - Eina_Bool delete_me:1; -}; - - -static Ecore_Idle_Exiter *idle_exiters = NULL; -static Ecore_Idle_Exiter *idle_exiter_current = NULL; -static int idle_exiters_delete_me = 0; - -/** - * Add an idle exiter handler. - * @param func The function to call when exiting an idle state. - * @param data The data to be passed to the @p func call - * @return A handle to the idle exiter callback on success. NULL otherwise. - * @ingroup Idle_Group - */ -EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Idle_Exiter *ie; - - if (!func) - return NULL; - ie = calloc(1, sizeof(Ecore_Idle_Exiter)); - if (!ie) - return NULL; - ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER); - ie->func = func; - ie->data = (void *) data; - idle_exiters = - (Ecore_Idle_Exiter *) - eina_inlist_append(EINA_INLIST_GET(idle_exiters), - EINA_INLIST_GET(ie)); - return ie; -} - -/** - * Delete an idle exiter handler from the list to be run on exiting idle state. - * @param idle_exiter The idle exiter to delete - * @return The data pointer that was being being passed to the handler if - * successful. NULL otherwise. - * @ingroup Idle_Group - */ -EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter * idle_exiter) -{ - if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER)) { - ECORE_MAGIC_FAIL(idle_exiter, ECORE_MAGIC_IDLE_EXITER, - "ecore_idle_exiter_del"); - return NULL; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_exiter->delete_me, NULL); - idle_exiter->delete_me = 1; - idle_exiters_delete_me = 1; - return idle_exiter->data; -} - -void _ecore_idle_exiter_shutdown(void) -{ - Ecore_Idle_Exiter *ie; - while ((ie = idle_exiters)) { - idle_exiters = - (Ecore_Idle_Exiter *) - eina_inlist_remove(EINA_INLIST_GET(idle_exiters), - EINA_INLIST_GET(idle_exiters)); - ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); - free(ie); - } - idle_exiters_delete_me = 0; - idle_exiter_current = NULL; -} - -void _ecore_idle_exiter_call(void) -{ - if (!idle_exiter_current) { - /* regular main loop, start from head */ - idle_exiter_current = idle_exiters; - } else { - /* recursive main loop, continue from where we were */ - idle_exiter_current = - (Ecore_Idle_Exiter *) - EINA_INLIST_GET(idle_exiter_current)->next; - } - - while (idle_exiter_current) { - Ecore_Idle_Exiter *ie = - (Ecore_Idle_Exiter *) idle_exiter_current; - if (!ie->delete_me) { - ie->references++; - if (!ie->func(ie->data)) { - if (!ie->delete_me) - ecore_idle_exiter_del(ie); - } - ie->references--; - } - if (idle_exiter_current) /* may have changed in recursive main loops */ - idle_exiter_current = - (Ecore_Idle_Exiter *) - EINA_INLIST_GET(idle_exiter_current)->next; - } - if (idle_exiters_delete_me) { - Ecore_Idle_Exiter *l; - int deleted_idler_exiters_in_use = 0; - - for (l = idle_exiters; l;) { - Ecore_Idle_Exiter *ie = l; - - l = (Ecore_Idle_Exiter *) EINA_INLIST_GET(l)->next; - if (ie->delete_me) { - if (ie->references) { - deleted_idler_exiters_in_use++; - continue; - } - - idle_exiters = - (Ecore_Idle_Exiter *) - eina_inlist_remove(EINA_INLIST_GET - (idle_exiters), - EINA_INLIST_GET - (ie)); - ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); - free(ie); - } - } - if (!deleted_idler_exiters_in_use) - idle_exiters_delete_me = 0; - } -} - -int _ecore_idle_exiter_exist(void) -{ - if (idle_exiters) - return 1; - return 0; -} diff --git a/tests/suite/ecore/src/lib/ecore_idler.c b/tests/suite/ecore/src/lib/ecore_idler.c deleted file mode 100644 index d5cd74c760..0000000000 --- a/tests/suite/ecore/src/lib/ecore_idler.c +++ /dev/null @@ -1,154 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include "Ecore.h" -#include "ecore_private.h" - - -struct _Ecore_Idler { - EINA_INLIST; - ECORE_MAGIC; - Ecore_Task_Cb func; - void *data; - int references; - Eina_Bool delete_me:1; -}; - - -static Ecore_Idler *idlers = NULL; -static Ecore_Idler *idler_current = NULL; -static int idlers_delete_me = 0; - -/** - * Add an idler handler. - * @param func The function to call when idling. - * @param data The data to be passed to this @p func call. - * @return A idler handle if successfully added. NULL otherwise. - * @ingroup Idle_Group - * - * Add an idler handle to the event loop, returning a handle on success and - * NULL otherwise. The function @p func will be called repeatedly while - * no other events are ready to be processed, as long as it returns 1 - * (or ECORE_CALLBACK_RENEW). A return of 0 (or ECORE_CALLBACK_CANCEL) deletes - * the idler. - * - * Idlers are useful for progressively prossessing data without blocking. - */ -EAPI Ecore_Idler *ecore_idler_add(Ecore_Task_Cb func, const void *data) -{ - Ecore_Idler *ie; - - if (!func) - return NULL; - ie = calloc(1, sizeof(Ecore_Idler)); - if (!ie) - return NULL; - ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER); - ie->func = func; - ie->data = (void *) data; - idlers = - (Ecore_Idler *) eina_inlist_append(EINA_INLIST_GET(idlers), - EINA_INLIST_GET(ie)); - return ie; -} - -/** - * Delete an idler callback from the list to be executed. - * @param idler The handle of the idler callback to delete - * @return The data pointer passed to the idler callback on success. NULL - * otherwise. - * @ingroup Idle_Group - */ -EAPI void *ecore_idler_del(Ecore_Idler * idler) -{ - if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER)) { - ECORE_MAGIC_FAIL(idler, ECORE_MAGIC_IDLER, - "ecore_idler_del"); - return NULL; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL); - idler->delete_me = 1; - idlers_delete_me = 1; - return idler->data; -} - -void _ecore_idler_shutdown(void) -{ - Ecore_Idler *ie; - while ((ie = idlers)) { - idlers = - (Ecore_Idler *) - eina_inlist_remove(EINA_INLIST_GET(idlers), - EINA_INLIST_GET(idlers)); - ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); - free(ie); - } - idlers_delete_me = 0; - idler_current = NULL; -} - -int _ecore_idler_call(void) -{ - if (!idler_current) { - /* regular main loop, start from head */ - idler_current = idlers; - } else { - /* recursive main loop, continue from where we were */ - idler_current = - (Ecore_Idler *) EINA_INLIST_GET(idler_current)->next; - } - - while (idler_current) { - Ecore_Idler *ie = (Ecore_Idler *) idler_current; - if (!ie->delete_me) { - ie->references++; - if (!ie->func(ie->data)) { - if (!ie->delete_me) - ecore_idler_del(ie); - } - ie->references--; - } - if (idler_current) /* may have changed in recursive main loops */ - idler_current = - (Ecore_Idler *) - EINA_INLIST_GET(idler_current)->next; - } - if (idlers_delete_me) { - Ecore_Idler *l; - int deleted_idlers_in_use = 0; - for (l = idlers; l;) { - Ecore_Idler *ie = l; - l = (Ecore_Idler *) EINA_INLIST_GET(l)->next; - if (ie->delete_me) { - if (ie->references) { - deleted_idlers_in_use++; - continue; - } - - idlers = - (Ecore_Idler *) - eina_inlist_remove(EINA_INLIST_GET - (idlers), - EINA_INLIST_GET - (ie)); - ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); - free(ie); - } - } - if (!deleted_idlers_in_use) - idlers_delete_me = 0; - } - if (idlers) - return 1; - return 0; -} - -int _ecore_idler_exist(void) -{ - if (idlers) - return 1; - return 0; -} diff --git a/tests/suite/ecore/src/lib/ecore_job.c b/tests/suite/ecore/src/lib/ecore_job.c deleted file mode 100644 index e9a8de169e..0000000000 --- a/tests/suite/ecore/src/lib/ecore_job.c +++ /dev/null @@ -1,104 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include "Ecore.h" -#include "ecore_private.h" - -static Eina_Bool _ecore_job_event_handler(void *data, int type, void *ev); -static void _ecore_job_event_free(void *data, void *ev); - -static int ecore_event_job_type = 0; -static Ecore_Event_Handler *_ecore_job_handler = NULL; - -struct _Ecore_Job { - ECORE_MAGIC; - Ecore_Event *event; - Ecore_Cb func; - void *data; -}; - -void _ecore_job_init(void) -{ - ecore_event_job_type = ecore_event_type_new(); - _ecore_job_handler = - ecore_event_handler_add(ecore_event_job_type, - _ecore_job_event_handler, NULL); -} - -void _ecore_job_shutdown(void) -{ - ecore_event_handler_del(_ecore_job_handler); - _ecore_job_handler = NULL; -} - -/** - * Add a job to the event queue. - * @param func The function to call when the job gets handled. - * @param data Data pointer to be passed to the job function when the job is - * handled. - * @return The handle of the job. @c NULL is returned if the job could not be - * added to the queue. - * @ingroup Ecore_Job_Group - * @note Once the job has been executed, the job handle is invalid. - */ -EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data) -{ - Ecore_Job *job; - - if (!func) - return NULL; - - job = calloc(1, sizeof(Ecore_Job)); - if (!job) - return NULL; - ECORE_MAGIC_SET(job, ECORE_MAGIC_JOB); - job->event = - ecore_event_add(ecore_event_job_type, job, - _ecore_job_event_free, NULL); - if (!job->event) { - free(job); - return NULL; - } - job->func = func; - job->data = (void *) data; - return job; -} - -/** - * Delete a queued job that has not yet been executed. - * @param job Handle of the job to delete. - * @return The data pointer that was to be passed to the job. - * @ingroup Ecore_Job_Group - */ -EAPI void *ecore_job_del(Ecore_Job * job) -{ - void *data; - - if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_JOB)) { - ECORE_MAGIC_FAIL(job, ECORE_MAGIC_JOB, "ecore_job_del"); - return NULL; - } - data = job->data; - ECORE_MAGIC_SET(job, ECORE_MAGIC_NONE); - ecore_event_del(job->event); - return data; -} - -static Eina_Bool -_ecore_job_event_handler(void *data __UNUSED__, int type __UNUSED__, - void *ev) -{ - Ecore_Job *job; - - job = ev; - job->func(job->data); - return ECORE_CALLBACK_CANCEL; -} - -static void _ecore_job_event_free(void *data __UNUSED__, void *ev) -{ - free(ev); -} diff --git a/tests/suite/ecore/src/lib/ecore_main.c b/tests/suite/ecore/src/lib/ecore_main.c deleted file mode 100644 index 6c22589114..0000000000 --- a/tests/suite/ecore/src/lib/ecore_main.c +++ /dev/null @@ -1,1415 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#undef WIN32_LEAN_AND_MEAN -#ifndef USER_TIMER_MINIMUM -#define USER_TIMER_MINIMUM 0x0a -#endif -#endif - -#ifdef __SUNPRO_C -#include <ieeefp.h> -#include <string.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <sys/types.h> -#include <errno.h> -#include <fcntl.h> - -#ifndef _MSC_VER -#include <sys/time.h> -#include <unistd.h> -#else -#include <float.h> -#endif - -#define FIX_HZ 1 - -#ifdef FIX_HZ -#ifndef _MSC_VER -#include <sys/param.h> -#endif -#ifndef HZ -#define HZ 100 -#endif -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -#ifdef HAVE_SYS_EPOLL_H -#define HAVE_EPOLL -#include <sys/epoll.h> -#endif - -#ifdef USE_G_MAIN_LOOP -#include <glib.h> -#endif - -struct _Ecore_Fd_Handler { - EINA_INLIST; - ECORE_MAGIC; - int fd; - Ecore_Fd_Handler_Flags flags; - Ecore_Fd_Cb func; - void *data; - Ecore_Fd_Cb buf_func; - void *buf_data; - Ecore_Fd_Prep_Cb prep_func; - void *prep_data; - int references; - Eina_Bool read_active:1; - Eina_Bool write_active:1; - Eina_Bool error_active:1; - Eina_Bool delete_me:1; -}; - -#ifdef _WIN32 -struct _Ecore_Win32_Handler { - EINA_INLIST; - ECORE_MAGIC; - HANDLE h; - Ecore_Fd_Win32_Cb func; - void *data; - int references; - Eina_Bool delete_me:1; -}; -#endif - - -static int _ecore_main_select(double timeout); -static void _ecore_main_prepare_handlers(void); -static void _ecore_main_fd_handlers_cleanup(void); -#ifndef _WIN32 -static void _ecore_main_fd_handlers_bads_rem(void); -#endif -static void _ecore_main_fd_handlers_call(void); -static int _ecore_main_fd_handlers_buf_call(void); -#ifndef USE_G_MAIN_LOOP -static void _ecore_main_loop_iterate_internal(int once_only); -#endif - -#ifdef _WIN32 -static int _ecore_main_win32_select(int nfds, fd_set * readfds, - fd_set * writefds, fd_set * exceptfds, - struct timeval *timeout); -static void _ecore_main_win32_handlers_cleanup(void); -#endif - -static int in_main_loop = 0; -static int do_quit = 0; -static Ecore_Fd_Handler *fd_handlers = NULL; -static Ecore_Fd_Handler *fd_handler_current = NULL; -static int fd_handlers_delete_me = 0; -#ifdef _WIN32 -static Ecore_Win32_Handler *win32_handlers = NULL; -static Ecore_Win32_Handler *win32_handler_current = NULL; -static int win32_handlers_delete_me = 0; -#endif - -#ifdef _WIN32 -static Ecore_Select_Function main_loop_select = _ecore_main_win32_select; -#else -static Ecore_Select_Function main_loop_select = select; -#endif - -static double t1 = 0.0; -static double t2 = 0.0; - -#ifdef HAVE_EPOLL -static int epoll_fd = -1; -#endif - -#ifdef USE_G_MAIN_LOOP -static GSource *ecore_epoll_source; -static GPollFD ecore_epoll_fd; -static guint ecore_epoll_id; -static GMainLoop *ecore_main_loop; -static gboolean ecore_idling; -static gboolean ecore_fds_ready; -#endif - -#ifdef HAVE_EPOLL -static inline int _ecore_poll_events_from_fdh(Ecore_Fd_Handler * fdh) -{ - int events = 0; - if (fdh->flags & ECORE_FD_READ) - events |= EPOLLIN; - if (fdh->flags & ECORE_FD_WRITE) - events |= EPOLLOUT; - if (fdh->flags & ECORE_FD_ERROR) - events |= EPOLLERR; - return events; -} -#else -static inline int _ecore_poll_events_from_fdh(Ecore_Fd_Handler * - fdh __UNUSED__) -{ - return 0; -} -#endif - -#ifdef HAVE_EPOLL -static inline int _ecore_main_fdh_epoll_add(Ecore_Fd_Handler * fdh) -{ - int r = 0; - struct epoll_event ev; - - memset(&ev, 0, sizeof(ev)); - ev.events = _ecore_poll_events_from_fdh(fdh); - ev.data.ptr = fdh; - INF("adding poll on %d %08x", fdh->fd, ev.events); - r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fdh->fd, &ev); - return r; -} -#else -static inline int _ecore_main_fdh_epoll_add(Ecore_Fd_Handler * - fdh __UNUSED__) -{ - return 0; -} -#endif - -#ifdef HAVE_EPOLL -static inline void _ecore_main_fdh_epoll_del(Ecore_Fd_Handler * fdh) -{ - struct epoll_event ev; - - memset(&ev, 0, sizeof(ev)); - INF("removing poll on %d", fdh->fd); - /* could get an EBADF if somebody closed the FD before removing it */ - if ((epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0) && - (errno != EBADF)) { - ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, - errno); - } -} -#else -static inline void _ecore_main_fdh_epoll_del(Ecore_Fd_Handler * - fdh __UNUSED__) -{ -} -#endif - -#ifdef HAVE_EPOLL -static inline int _ecore_main_fdh_epoll_modify(Ecore_Fd_Handler * fdh) -{ - int r = 0; - struct epoll_event ev; - - memset(&ev, 0, sizeof(ev)); - ev.events = _ecore_poll_events_from_fdh(fdh); - ev.data.ptr = fdh; - INF("modifing epoll on %d to %08x", fdh->fd, ev.events); - r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fdh->fd, &ev); - return r; -} -#else -static inline int _ecore_main_fdh_epoll_modify(Ecore_Fd_Handler * - fdh __UNUSED__) -{ - return 0; -} -#endif - -#ifdef HAVE_EPOLL -static inline int _ecore_main_fdh_epoll_mark_active(void) -{ - struct epoll_event ev[32]; - int i, ret; - - memset(&ev, 0, sizeof(ev)); - ret = - epoll_wait(epoll_fd, ev, - sizeof(ev) / sizeof(struct epoll_event), 0); - if (ret < 0) { - if (errno == EINTR) - return -1; - ERR("epoll_wait failed %d", errno); - return -1; - } - - for (i = 0; i < ret; i++) { - Ecore_Fd_Handler *fdh; - - fdh = ev[i].data.ptr; - if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER)) { - ECORE_MAGIC_FAIL(fdh, ECORE_MAGIC_FD_HANDLER, - "_ecore_main_fdh_epoll_mark_active"); - continue; - } - if (fdh->delete_me) { - ERR("deleted fd in epoll"); - continue; - } - if (ev->events & EPOLLIN) - fdh->read_active = 1; - if (ev->events & EPOLLOUT) - fdh->write_active = 1; - if (ev->events & EPOLLERR) - fdh->error_active = 1; - } - - return ret; -} -#endif - -#ifdef USE_G_MAIN_LOOP - -/* like we are about to enter main_loop_select in _ecore_main_select */ -static gboolean -_ecore_main_gsource_prepare(GSource * source, gint * next_time) -{ - double t = _ecore_timer_next_get(); - gboolean running; - - INF("enter, next timeout in %.1f", t); - in_main_loop++; - - if (!ecore_idling) { - while (_ecore_timer_call(_ecore_time_loop_time)); - _ecore_timer_cleanup(); - - /* when idling, busy loop checking the fds only */ - if (!ecore_idling) - _ecore_idle_enterer_call(); - } - - /* don't check fds if somebody quit */ - running = g_main_loop_is_running(ecore_main_loop); - if (running) { - /* only set idling state in dispatch */ - if (ecore_idling && !_ecore_idler_exist()) { - if (_ecore_timers_exists()) { - double t = _ecore_timer_next_get(); - *next_time = (t / 1000.0); - } else - *next_time = -1; - } else - *next_time = 0; - - _ecore_main_prepare_handlers(); - } - - in_main_loop--; - INF("leave, timeout = %d", *next_time); - - /* ready if we're not running (about to quit) */ - return !running; -} - -static gboolean _ecore_main_gsource_check(GSource * source) -{ - INF("enter"); - in_main_loop++; - - ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active() > 0); - _ecore_main_fd_handlers_cleanup(); - - _ecore_time_loop_time = ecore_time_get(); - _ecore_timer_enable_new(); - - in_main_loop--; - INF("leave"); - - return TRUE; /* always dispatch */ -} - -/* like we just came out of main_loop_select in _ecore_main_select */ -static gboolean -_ecore_main_gsource_dispatch(GSource * source, GSourceFunc callback, - gpointer user_data) -{ - gboolean events_ready, timers_ready, idlers_ready, signals_ready; - double next_time = _ecore_timer_next_get(); - - events_ready = _ecore_event_exist(); - timers_ready = _ecore_timers_exists() && (0.0 <= next_time); - idlers_ready = _ecore_idler_exist(); - signals_ready = (_ecore_signal_count_get() > 0); - - in_main_loop++; - INF("enter idling=%d fds=%d events=%d signals=%d timers=%d (next=%.2f) idlers=%d", ecore_idling, ecore_fds_ready, events_ready, signals_ready, _ecore_timers_exists(), next_time, idlers_ready); - - if (ecore_idling && events_ready) { - INF("calling idle exiters"); - _ecore_idle_exiter_call(); - ecore_idling = 0; - } else if (!ecore_idling && !events_ready) { - INF("start idling"); - ecore_idling = 1; - } - - if (ecore_idling) { - INF("calling idler"); - _ecore_idler_call(); - - events_ready = _ecore_event_exist(); - timers_ready = _ecore_timers_exists() - && (0.0 <= next_time); - idlers_ready = _ecore_idler_exist(); - - if ((ecore_fds_ready || events_ready || timers_ready - || idlers_ready || signals_ready)) { - INF("calling idle exiters"); - _ecore_idle_exiter_call(); - ecore_idling = 0; - } - } - - /* process events */ - if (!ecore_idling) { - INF("work"); - _ecore_main_fd_handlers_call(); - _ecore_main_fd_handlers_buf_call(); - while (_ecore_signal_count_get()) - _ecore_signal_call(); - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); - } - - in_main_loop--; - - INF("leave"); - - return TRUE; /* what should be returned here? */ -} - -static void _ecore_main_gsource_finalize(GSource * source) -{ - INF("finalize"); -} - -static GSourceFuncs ecore_gsource_funcs = { - .prepare = _ecore_main_gsource_prepare, - .check = _ecore_main_gsource_check, - .dispatch = _ecore_main_gsource_dispatch, - .finalize = _ecore_main_gsource_finalize, -}; - -#endif - -void _ecore_main_loop_init(void) -{ - INF("enter"); -#ifdef HAVE_EPOLL - epoll_fd = epoll_create(1); - if (epoll_fd < 0) - CRIT("Failed to create epoll fd!"); -#endif - -#ifdef USE_G_MAIN_LOOP - ecore_epoll_source = - g_source_new(&ecore_gsource_funcs, sizeof(GSource)); - if (!ecore_epoll_source) - CRIT("Failed to create glib source for epoll!"); - else { - ecore_epoll_fd.fd = epoll_fd; - ecore_epoll_fd.events = G_IO_IN; - ecore_epoll_fd.revents = 0; - g_source_add_poll(ecore_epoll_source, &ecore_epoll_fd); - ecore_epoll_id = g_source_attach(ecore_epoll_source, NULL); - if (ecore_epoll_id <= 0) - CRIT("Failed to attach glib source to default context"); - } -#endif - INF("leave"); -} - -void _ecore_main_loop_shutdown(void) -{ -#ifdef USE_G_MAIN_LOOP - if (ecore_epoll_source) { - g_source_destroy(ecore_epoll_source); - ecore_epoll_source = NULL; - } -#endif - -#ifdef HAVE_EPOLL - if (epoll_fd >= 0) { - close(epoll_fd); - epoll_fd = -1; - } -#endif -} - - -/** - * @defgroup Ecore_Main_Loop_Group Main Loop Functions - * - * These functions control the Ecore event handling loop. This loop is - * designed to work on embedded systems all the way to large and - * powerful mutli-cpu workstations. - * - * It serialises all system signals and events into a single event - * queue, that can be easily processed without needing to worry about - * concurrency. A properly written, event-driven program using this - * kind of programming does not need threads. It makes the program very - * robust and easy to follow. - * - * Here is an example of simple program and its basic event loop flow: - * @image html prog_flow.png - * - * For examples of setting up and using a main loop, see - * @ref event_handler_example.c and @ref timer_example.c. - */ - -/** - * Runs a single iteration of the main loop to process everything on the - * queue. - * @ingroup Ecore_Main_Loop_Group - */ -EAPI void ecore_main_loop_iterate(void) -{ -#ifndef USE_G_MAIN_LOOP - _ecore_main_loop_iterate_internal(1); -#else - g_main_context_iteration(NULL, 1); -#endif -} - -/** - * Runs the application main loop. - * - * This function will not return until @ref ecore_main_loop_quit is called. - * - * @ingroup Ecore_Main_Loop_Group - */ -EAPI void ecore_main_loop_begin(void) -{ -#ifndef USE_G_MAIN_LOOP - in_main_loop++; - while (do_quit == 0) - _ecore_main_loop_iterate_internal(0); - do_quit = 0; - in_main_loop--; -#else - ecore_main_loop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(ecore_main_loop); -#endif -} - -/** - * Quits the main loop once all the events currently on the queue have - * been processed. - * @ingroup Ecore_Main_Loop_Group - */ -EAPI void ecore_main_loop_quit(void) -{ -#ifndef USE_G_MAIN_LOOP - do_quit = 1; -#else - INF("enter"); - g_main_loop_quit(ecore_main_loop); - INF("leave"); -#endif -} - -/** - * Sets the function to use when monitoring multiple file descriptors, - * and waiting until one of more of the file descriptors before ready - * for some class of I/O operation. - * - * This function will be used instead of the system call select and - * could possible be used to integrate the Ecore event loop with an - * external event loop. - * - * @warning you don't know how to use, don't even try to use it. - * - * @ingroup Ecore_Main_Loop_Group - */ -EAPI void ecore_main_loop_select_func_set(Ecore_Select_Function func) -{ - main_loop_select = func; -} - -/** - * Gets the select function set by ecore_select_func_set(), - * or the native select function if none was set. - * - * @ingroup Ecore_Main_Loop_Group - */ -EAPI void *ecore_main_loop_select_func_get(void) -{ - return main_loop_select; -} - -/** - * @defgroup Ecore_FD_Handler_Group File Event Handling Functions - * - * Functions that deal with file descriptor handlers. - */ - -/** - * Adds a callback for activity on the given file descriptor. - * - * @p func will be called during the execution of @ref ecore_main_loop_begin - * when the file descriptor is available for reading, or writing, or both. - * - * Normally the return value from the @p func is "zero means this handler is - * finished and can be deleted" as is usual for handler callbacks. However, - * if the @p buf_func is supplied, then the return value from the @p func is - * "non zero means the handler should be called again in a tight loop". - * - * @p buf_func is called during event loop handling to check if data that has - * been read from the file descriptor is in a buffer and is available to - * read. Some systems (notably xlib) handle their own buffering, and would - * otherwise not work with select(). These systems should use a @p buf_func. - * This is a most annoying hack, only ecore_x uses it, so refer to that for - * an example. NOTE - @p func should probably return "one" always if - * @p buf_func is used, to avoid confusion with the other return value - * semantics. - * - * @param fd The file descriptor to watch. - * @param flags To watch it for read (@c ECORE_FD_READ) and/or - * (@c ECORE_FD_WRITE) write ability. @c ECORE_FD_ERROR - * - * @param func The callback function. - * @param data The data to pass to the callback. - * @param buf_func The function to call to check if any data has been - * buffered and already read from the fd. Can be @c NULL. - * @param buf_data The data to pass to the @p buf_func function. - * @return A fd handler handle if successful. @c NULL otherwise. - * @ingroup Ecore_FD_Handler_Group - */ -EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, - Ecore_Fd_Handler_Flags - flags, Ecore_Fd_Cb func, - const void *data, - Ecore_Fd_Cb buf_func, - const void *buf_data) -{ - Ecore_Fd_Handler *fdh; - - if ((fd < 0) || (flags == 0) || (!func)) - return NULL; - - fdh = calloc(1, sizeof(Ecore_Fd_Handler)); - if (!fdh) - return NULL; - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); - fdh->fd = fd; - fdh->flags = flags; - if (0 > _ecore_main_fdh_epoll_add(fdh)) { - ERR("Failed to add epoll fd %d (errno = %d)!", fd, errno); - free(fdh); - return NULL; - } - fdh->read_active = 0; - fdh->write_active = 0; - fdh->error_active = 0; - fdh->delete_me = 0; - fdh->func = func; - fdh->data = (void *) data; - fdh->buf_func = buf_func; - fdh->buf_data = (void *) buf_data; - fd_handlers = (Ecore_Fd_Handler *) - eina_inlist_append(EINA_INLIST_GET(fd_handlers), - EINA_INLIST_GET(fdh)); - return fdh; -} - -#ifdef _WIN32 -EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, - Ecore_Fd_Win32_Cb - func, - const void *data) -{ - Ecore_Win32_Handler *wh; - - if (!h || !func) - return NULL; - - wh = calloc(1, sizeof(Ecore_Win32_Handler)); - if (!wh) - return NULL; - ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER); - wh->h = (HANDLE) h; - wh->delete_me = 0; - wh->func = func; - wh->data = (void *) data; - win32_handlers = (Ecore_Win32_Handler *) - eina_inlist_append(EINA_INLIST_GET(win32_handlers), - EINA_INLIST_GET(wh)); - return wh; -} -#else -EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h __UNUSED__, - Ecore_Fd_Win32_Cb - func __UNUSED__, - const void *data - __UNUSED__) -{ - return NULL; -} -#endif - -/** - * Deletes the given FD handler. - * @param fd_handler The given FD handler. - * @return The data pointer set using @ref ecore_main_fd_handler_add, - * for @p fd_handler on success. @c NULL otherwise. - * @ingroup Ecore_FD_Handler_Group - * - * Beware that if the fd is already closed, ecore may complain if it uses - * epoll internally, and that in some rare cases this may be able to cause - * crashes and instability. Remember to delete your fd handlers before the - * fd's they listen to are closed. - */ -EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler * fd_handler) -{ - if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) { - ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, - "ecore_main_fd_handler_del"); - return NULL; - } - fd_handler->delete_me = 1; - fd_handlers_delete_me = 1; - _ecore_main_fdh_epoll_del(fd_handler); - return fd_handler->data; -} - -#ifdef _WIN32 -EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler * - win32_handler) -{ - if (!ECORE_MAGIC_CHECK(win32_handler, ECORE_MAGIC_WIN32_HANDLER)) { - ECORE_MAGIC_FAIL(win32_handler, ECORE_MAGIC_WIN32_HANDLER, - "ecore_main_win32_handler_del"); - return NULL; - } - win32_handler->delete_me = 1; - win32_handlers_delete_me = 1; - return win32_handler->data; -} -#else -EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler * - win32_handler __UNUSED__) -{ - return NULL; -} -#endif - -EAPI void -ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler * fd_handler, - Ecore_Fd_Prep_Cb func, - const void *data) -{ - if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) { - ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, - "ecore_main_fd_handler_prepare_callback_set"); - return; - } - fd_handler->prep_func = func; - fd_handler->prep_data = (void *) data; -} - -/** - * Retrieves the file descriptor that the given handler is handling. - * @param fd_handler The given FD handler. - * @return The file descriptor the handler is watching. - * @ingroup Ecore_FD_Handler_Group - */ -EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler * fd_handler) -{ - if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) { - ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, - "ecore_main_fd_handler_fd_get"); - return -1; - } - return fd_handler->fd; -} - -/** - * Return if read, write or error, or a combination thereof, is active on the - * file descriptor of the given FD handler. - * @param fd_handler The given FD handler. - * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or - * @c ECORE_FD_ERROR to query. - * @return #EINA_TRUE if any of the given flags are active. #EINA_FALSE otherwise. - * @ingroup Ecore_FD_Handler_Group - */ -EAPI Eina_Bool -ecore_main_fd_handler_active_get(Ecore_Fd_Handler * fd_handler, - Ecore_Fd_Handler_Flags flags) -{ - int ret = EINA_FALSE; - - if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) { - ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, - "ecore_main_fd_handler_active_get"); - return EINA_FALSE; - } - if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) - ret = EINA_TRUE; - if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) - ret = EINA_TRUE; - if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) - ret = EINA_TRUE; - return ret; -} - -/** - * Set what active streams the given FD handler should be monitoring. - * @param fd_handler The given FD handler. - * @param flags The flags to be watching. - * @ingroup Ecore_FD_Handler_Group - */ -EAPI void -ecore_main_fd_handler_active_set(Ecore_Fd_Handler * fd_handler, - Ecore_Fd_Handler_Flags flags) -{ - if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) { - ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, - "ecore_main_fd_handler_active_set"); - return; - } - fd_handler->flags = flags; - if (0 > _ecore_main_fdh_epoll_modify(fd_handler)) { - ERR("Failed to mod epoll fd %d!", fd_handler->fd); - } -} - -void _ecore_main_shutdown(void) -{ - if (in_main_loop) { - ERR("\n" - "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n" - "*** Program may crash or behave strangely now."); - return; - } - while (fd_handlers) { - Ecore_Fd_Handler *fdh; - - fdh = fd_handlers; - fd_handlers = - (Ecore_Fd_Handler *) - eina_inlist_remove(EINA_INLIST_GET(fd_handlers), - EINA_INLIST_GET(fdh)); - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); - free(fdh); - } - fd_handlers_delete_me = 0; - fd_handler_current = NULL; - -#ifdef _WIN32 - while (win32_handlers) { - Ecore_Win32_Handler *wh; - - wh = win32_handlers; - win32_handlers = - (Ecore_Win32_Handler *) - eina_inlist_remove(EINA_INLIST_GET(win32_handlers), - EINA_INLIST_GET(wh)); - ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE); - free(wh); - } - win32_handlers_delete_me = 0; - win32_handler_current = NULL; -#endif -} - -static void _ecore_main_prepare_handlers(void) -{ - Ecore_Fd_Handler *fdh; - - /* call the prepare callback for all handlers */ - EINA_INLIST_FOREACH(fd_handlers, fdh) { - if (!fdh->delete_me && fdh->prep_func) { - fdh->references++; - fdh->prep_func(fdh->prep_data, fdh); - fdh->references--; - } - } -} - -static int _ecore_main_select(double timeout) -{ - struct timeval tv, *t; - fd_set rfds, wfds, exfds; - int max_fd; - int ret; - - t = NULL; - if ((!finite(timeout)) || (timeout == 0.0)) { /* finite() tests for NaN, too big, too small, and infinity. */ - tv.tv_sec = 0; - tv.tv_usec = 0; - t = &tv; - } else if (timeout > 0.0) { - int sec, usec; - -#ifdef FIX_HZ - timeout += (0.5 / HZ); - sec = (int) timeout; - usec = (int) ((timeout - (double) sec) * 1000000); -#else - sec = (int) timeout; - usec = (int) ((timeout - (double) sec) * 1000000); -#endif - tv.tv_sec = sec; - tv.tv_usec = usec; - t = &tv; - } - max_fd = 0; - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&exfds); - - /* call the prepare callback for all handlers */ - _ecore_main_prepare_handlers(); -#ifndef HAVE_EPOLL - Ecore_Fd_Handler *fdh; - - EINA_INLIST_FOREACH(fd_handlers, fdh) { - if (!fdh->delete_me) { - if (fdh->flags & ECORE_FD_READ) { - FD_SET(fdh->fd, &rfds); - if (fdh->fd > max_fd) - max_fd = fdh->fd; - } - if (fdh->flags & ECORE_FD_WRITE) { - FD_SET(fdh->fd, &wfds); - if (fdh->fd > max_fd) - max_fd = fdh->fd; - } - if (fdh->flags & ECORE_FD_ERROR) { - FD_SET(fdh->fd, &exfds); - if (fdh->fd > max_fd) - max_fd = fdh->fd; - } - } - } -#else /* HAVE_EPOLL */ - /* polling on the epoll fd will wake when an fd in the epoll set is active */ - FD_SET(epoll_fd, &rfds); - max_fd = epoll_fd; -#endif /* HAVE_EPOLL */ - - if (_ecore_signal_count_get()) - return -1; - - ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t); - - _ecore_time_loop_time = ecore_time_get(); - if (ret < 0) { -#ifndef _WIN32 - if (errno == EINTR) - return -1; - else if (errno == EBADF) - _ecore_main_fd_handlers_bads_rem(); -#endif - } - if (ret > 0) { -#ifdef HAVE_EPOLL - _ecore_main_fdh_epoll_mark_active(); -#else /* HAVE_EPOLL */ - Ecore_Fd_Handler *fdh; - - EINA_INLIST_FOREACH(fd_handlers, fdh) { - if (!fdh->delete_me) { - if (FD_ISSET(fdh->fd, &rfds)) - fdh->read_active = 1; - if (FD_ISSET(fdh->fd, &wfds)) - fdh->write_active = 1; - if (FD_ISSET(fdh->fd, &exfds)) - fdh->error_active = 1; - } - } -#endif /* HAVE_EPOLL */ - _ecore_main_fd_handlers_cleanup(); -#ifdef _WIN32 - _ecore_main_win32_handlers_cleanup(); -#endif - return 1; - } - return 0; -} - -#ifndef _WIN32 -static void _ecore_main_fd_handlers_bads_rem(void) -{ - Ecore_Fd_Handler *fdh; - Eina_Inlist *l; - int found = 0; - - ERR("Removing bad fds"); - for (l = EINA_INLIST_GET(fd_handlers); l;) { - fdh = (Ecore_Fd_Handler *) l; - l = l->next; - errno = 0; - - if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF)) { - ERR("Found bad fd at index %d", fdh->fd); - if (fdh->flags & ECORE_FD_ERROR) { - ERR("Fd set for error! calling user"); - fdh->references++; - if (!fdh->func(fdh->data, fdh)) { - ERR("Fd function err returned 0, remove it"); - fdh->delete_me = 1; - fd_handlers_delete_me = 1; - found++; - } - fdh->references--; - } else { - ERR("Problematic fd found at %d! setting it for delete", fdh->fd); - fdh->delete_me = 1; - fd_handlers_delete_me = 1; - found++; - } - } - } - if (found == 0) { -#ifdef HAVE_GLIB - ERR("No bad fd found. Maybe a foreign fd from glib?"); -#else - ERR("No bad fd found. EEEK!"); -#endif - } - _ecore_main_fd_handlers_cleanup(); -} -#endif - -static void _ecore_main_fd_handlers_cleanup(void) -{ - Ecore_Fd_Handler *fdh; - Eina_Inlist *l; - int deleted_in_use = 0; - - if (!fd_handlers_delete_me) - return; - for (l = EINA_INLIST_GET(fd_handlers); l;) { - fdh = (Ecore_Fd_Handler *) l; - - l = l->next; - if (fdh->delete_me) { - if (fdh->references) { - deleted_in_use++; - continue; - } - - fd_handlers = (Ecore_Fd_Handler *) - eina_inlist_remove(EINA_INLIST_GET - (fd_handlers), - EINA_INLIST_GET(fdh)); - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); - free(fdh); - } - } - if (!deleted_in_use) - fd_handlers_delete_me = 0; -} - -#ifdef _WIN32 -static void _ecore_main_win32_handlers_cleanup(void) -{ - Ecore_Win32_Handler *wh; - Eina_Inlist *l; - int deleted_in_use = 0; - - if (!win32_handlers_delete_me) - return; - for (l = EINA_INLIST_GET(win32_handlers); l;) { - wh = (Ecore_Win32_Handler *) l; - - l = l->next; - if (wh->delete_me) { - if (wh->references) { - deleted_in_use++; - continue; - } - - win32_handlers = (Ecore_Win32_Handler *) - eina_inlist_remove(EINA_INLIST_GET - (win32_handlers), - EINA_INLIST_GET(wh)); - ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE); - free(wh); - } - } - if (!deleted_in_use) - win32_handlers_delete_me = 0; -} -#endif - -static void _ecore_main_fd_handlers_call(void) -{ - if (!fd_handler_current) { - /* regular main loop, start from head */ - fd_handler_current = fd_handlers; - } else { - /* recursive main loop, continue from where we were */ - fd_handler_current = - (Ecore_Fd_Handler *) - EINA_INLIST_GET(fd_handler_current)->next; - } - - while (fd_handler_current) { - Ecore_Fd_Handler *fdh = fd_handler_current; - - if (!fdh->delete_me) { - if ((fdh->read_active) || - (fdh->write_active) || (fdh->error_active)) { - fdh->references++; - if (!fdh->func(fdh->data, fdh)) { - fdh->delete_me = 1; - fd_handlers_delete_me = 1; - } - fdh->references--; - - fdh->read_active = 0; - fdh->write_active = 0; - fdh->error_active = 0; - } - } - - if (fd_handler_current) /* may have changed in recursive main loops */ - fd_handler_current = - (Ecore_Fd_Handler *) - EINA_INLIST_GET(fd_handler_current)->next; - } -} - -static int _ecore_main_fd_handlers_buf_call(void) -{ - Ecore_Fd_Handler *fdh; - int ret; - - ret = 0; - EINA_INLIST_FOREACH(fd_handlers, fdh) { - if (!fdh->delete_me) { - if (fdh->buf_func) { - fdh->references++; - if (fdh->buf_func(fdh->buf_data, fdh)) { - ret |= fdh->func(fdh->data, fdh); - fdh->read_active = 1; - } - fdh->references--; - } - } - } - return ret; -} - -#ifndef USE_G_MAIN_LOOP -static void _ecore_main_loop_iterate_internal(int once_only) -{ - double next_time = -1.0; - int have_event = 0; - int have_signal; - - in_main_loop++; - /* expire any timers */ - while (_ecore_timer_call(_ecore_time_loop_time)); - _ecore_timer_cleanup(); - - /* process signals into events .... */ - while (_ecore_signal_count_get()) - _ecore_signal_call(); - if (_ecore_event_exist()) { - _ecore_idle_enterer_call(); - have_event = 1; - _ecore_main_select(0.0); - _ecore_time_loop_time = ecore_time_get(); - _ecore_timer_enable_new(); - goto process_events; - } - /* call idle enterers ... */ - if (!once_only) - _ecore_idle_enterer_call(); - else { - have_event = have_signal = 0; - - if (_ecore_main_select(0.0) > 0) - have_event = 1; - if (_ecore_signal_count_get() > 0) - have_signal = 1; - if (have_signal || have_event) { - _ecore_time_loop_time = ecore_time_get(); - _ecore_timer_enable_new(); - goto process_events; - } - } - - /* if these calls caused any buffered events to appear - deal with them */ - _ecore_main_fd_handlers_buf_call(); - - /* if there are any - jump to processing them */ - if (_ecore_event_exist()) { - have_event = 1; - _ecore_main_select(0.0); - _ecore_time_loop_time = ecore_time_get(); - _ecore_timer_enable_new(); - goto process_events; - } - if (once_only) { - _ecore_idle_enterer_call(); - in_main_loop--; - _ecore_time_loop_time = ecore_time_get(); - _ecore_timer_enable_new(); - return; - } - - if (_ecore_fps_debug) { - t2 = ecore_time_get(); - if ((t1 > 0.0) && (t2 > 0.0)) - _ecore_fps_debug_runtime_add(t2 - t1); - } - start_loop: - /* any timers re-added as a result of these are allowed to go */ - _ecore_timer_enable_new(); - if (do_quit) { - _ecore_time_loop_time = ecore_time_get(); - in_main_loop--; - _ecore_timer_enable_new(); - return; - } - if (!_ecore_event_exist()) { - /* init flags */ - have_event = have_signal = 0; - next_time = _ecore_timer_next_get(); - /* no timers */ - if (next_time < 0) { - /* no idlers */ - if (!_ecore_idler_exist()) { - if (_ecore_main_select(-1.0) > 0) - have_event = 1; - } - /* idlers */ - else { - for (;;) { - if (!_ecore_idler_call()) - goto start_loop; - if (_ecore_event_exist()) - break; - if (_ecore_main_select(0.0) > 0) - have_event = 1; - if (_ecore_signal_count_get() > 0) - have_signal = 1; - if (have_event || have_signal) - break; - if (_ecore_timers_exists()) - goto start_loop; - if (do_quit) - break; - } - } - } - /* timers */ - else { - /* no idlers */ - if (!_ecore_idler_exist()) { - if (_ecore_main_select(next_time) > 0) - have_event = 1; - } - /* idlers */ - else { - for (;;) { - if (!_ecore_idler_call()) - goto start_loop; - if (_ecore_event_exist()) - break; - if (_ecore_main_select(0.0) > 0) - have_event = 1; - if (_ecore_signal_count_get() > 0) - have_signal = 1; - if (have_event || have_signal) - break; - next_time = - _ecore_timer_next_get(); - if (next_time <= 0) - break; - if (do_quit) - break; - } - } - } - _ecore_time_loop_time = ecore_time_get(); - } - if (_ecore_fps_debug) - t1 = ecore_time_get(); - /* we came out of our "wait state" so idle has exited */ - if (!once_only) - _ecore_idle_exiter_call(); - /* call the fd handler per fd that became alive... */ - /* this should read or write any data to the monitored fd and then */ - /* post events onto the ecore event pipe if necessary */ - process_events: - _ecore_main_fd_handlers_call(); - _ecore_main_fd_handlers_buf_call(); - /* process signals into events .... */ - while (_ecore_signal_count_get()) - _ecore_signal_call(); - /* handle events ... */ - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); - - if (once_only) - _ecore_idle_enterer_call(); - in_main_loop--; -} -#endif - -#ifdef _WIN32 -static int -_ecore_main_win32_select(int nfds __UNUSED__, fd_set * readfds, - fd_set * writefds, fd_set * exceptfds, - struct timeval *tv) -{ - HANDLE objects[MAXIMUM_WAIT_OBJECTS]; - int sockets[MAXIMUM_WAIT_OBJECTS]; - Ecore_Fd_Handler *fdh; - Ecore_Win32_Handler *wh; - unsigned int objects_nbr = 0; - unsigned int handles_nbr = 0; - unsigned int events_nbr = 0; - DWORD result; - DWORD timeout; - MSG msg; - unsigned int i; - int res; - - /* Create an event object per socket */ - EINA_INLIST_FOREACH(fd_handlers, fdh) { - WSAEVENT event; - long network_event; - - network_event = 0; - if (FD_ISSET(fdh->fd, readfds)) - network_event |= FD_READ; - if (FD_ISSET(fdh->fd, writefds)) - network_event |= FD_WRITE; - if (FD_ISSET(fdh->fd, exceptfds)) - network_event |= FD_OOB; - - if (network_event) { - event = WSACreateEvent(); - WSAEventSelect(fdh->fd, event, network_event); - objects[objects_nbr] = event; - sockets[events_nbr] = fdh->fd; - events_nbr++; - objects_nbr++; - } - } - - /* store the HANDLEs in the objects to wait for */ - EINA_INLIST_FOREACH(win32_handlers, wh) { - objects[objects_nbr] = wh->h; - handles_nbr++; - objects_nbr++; - } - - /* Empty the queue before waiting */ - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - /* Wait for any message sent or posted to this queue */ - /* or for one of the passed handles be set to signaled. */ - if (!tv) - timeout = INFINITE; - else - timeout = - (DWORD) ((tv->tv_sec * 1000.0) + - (tv->tv_usec / 1000.0)); - - if (timeout == 0) - return 0; - - result = - MsgWaitForMultipleObjects(objects_nbr, - (const HANDLE *) objects, EINA_FALSE, - timeout, QS_ALLINPUT); - - FD_ZERO(readfds); - FD_ZERO(writefds); - FD_ZERO(exceptfds); - - /* The result tells us the type of event we have. */ - if (result == WAIT_FAILED) { - char *msg; - - msg = evil_last_error_get(); - ERR(" * %s\n", msg); - free(msg); - res = -1; - } else if (result == WAIT_TIMEOUT) { - /* ERR("time out\n"); */ - res = 0; - } else if (result == (WAIT_OBJECT_0 + objects_nbr)) { - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - res = 0; - } else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr)) { - WSANETWORKEVENTS network_event; - - WSAEnumNetworkEvents(sockets[result], objects[result], - &network_event); - - if (network_event.lNetworkEvents & FD_READ) - FD_SET(sockets[result], readfds); - if (network_event.lNetworkEvents & FD_WRITE) - FD_SET(sockets[result], writefds); - if (network_event.lNetworkEvents & FD_OOB) - FD_SET(sockets[result], exceptfds); - - res = 1; - } else if ((result >= (WAIT_OBJECT_0 + events_nbr)) && - (result < (WAIT_OBJECT_0 + objects_nbr))) { - if (!win32_handler_current) { - /* regular main loop, start from head */ - win32_handler_current = win32_handlers; - } else { - /* recursive main loop, continue from where we were */ - win32_handler_current = - (Ecore_Win32_Handler *) - EINA_INLIST_GET(win32_handler_current)->next; - } - - while (win32_handler_current) { - wh = win32_handler_current; - - if (objects[result - WAIT_OBJECT_0] == wh->h) { - if (!wh->delete_me) { - wh->references++; - if (!wh->func(wh->data, wh)) { - wh->delete_me = 1; - win32_handlers_delete_me = - 1; - } - wh->references--; - } - } - if (win32_handler_current) /* may have changed in recursive main loops */ - win32_handler_current = - (Ecore_Win32_Handler *) - EINA_INLIST_GET - (win32_handler_current)->next; - } - res = 1; - } else { - ERR("unknown result...\n"); - res = -1; - } - - /* Remove event objects again */ - for (i = 0; i < events_nbr; i++) - WSACloseEvent(objects[i]); - - return res; -} -#endif diff --git a/tests/suite/ecore/src/lib/ecore_pipe.c b/tests/suite/ecore/src/lib/ecore_pipe.c deleted file mode 100644 index 123cab681b..0000000000 --- a/tests/suite/ecore/src/lib/ecore_pipe.c +++ /dev/null @@ -1,568 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -/* How of then we should retry to write to the pipe */ -#define ECORE_PIPE_WRITE_RETRY 6 - -/* - * On Windows, pipe() is implemented with sockets. - * Contrary to Linux, Windows uses different functions - * for sockets and fd's: write() is for fd's and send - * is for sockets. So I need to put some win32 code - * here. I can't think of a solution where the win32 - * code is in Evil and not here. - */ - -#ifdef _WIN32 - -#include <winsock2.h> - -#define pipe_write(fd, buffer, size) send((fd), (char *)(buffer), size, 0) -#define pipe_read(fd, buffer, size) recv((fd), (char *)(buffer), size, 0) -#define pipe_close(fd) closesocket(fd) -#define PIPE_FD_INVALID INVALID_SOCKET -#define PIPE_FD_ERROR SOCKET_ERROR - -#else - -#include <unistd.h> -#include <fcntl.h> - -#define pipe_write(fd, buffer, size) write((fd), buffer, size) -#define pipe_read(fd, buffer, size) read((fd), buffer, size) -#define pipe_close(fd) close(fd) -#define PIPE_FD_INVALID -1 -#define PIPE_FD_ERROR -1 - -#endif /* ! _WIN32 */ - -struct _Ecore_Pipe { - ECORE_MAGIC; - int fd_read; - int fd_write; - Ecore_Fd_Handler *fd_handler; - const void *data; - Ecore_Pipe_Cb handler; - unsigned int len; - size_t already_read; - void *passed_data; -}; - - -static Eina_Bool _ecore_pipe_read(void *data, - Ecore_Fd_Handler * fd_handler); - -/** - * @defgroup Ecore_Pipe_Group Pipe wrapper - * - * These functions wrap the pipe / write / read functions to - * easily integrate a loop that is in its own thread to the ecore - * main loop. - * - * The ecore_pipe_add() function creates file descriptors (sockets on - * Windows) and attach an handle to the ecore main loop. That handle is - * called when data is read in the pipe. To write data in the pipe, - * just call ecore_pipe_write(). When you are done, just call - * ecore_pipe_del(). - * - * Here is an example that uses the pipe wrapper with a Gstreamer - * pipeline. For each decoded frame in the Gstreamer thread, a handle - * is called in the ecore thread. - * - * @code#include <gst/gst.h> - * #include <Ecore.h> - * - * static int nbr = 0; - * - * static GstElement *_buid_pipeline (gchar *filename, Ecore_Pipe *pipe); - * - * static void new_decoded_pad_cb (GstElement *demuxer, - * GstPad *new_pad, - * gpointer user_data); - * - * static void handler(void *data, void *buf, unsigned int len) - * { - * GstBuffer *buffer = *((GstBuffer **)buf); - * - * printf ("handler : %p\n", buffer); - * printf ("frame : %d %p %lld %p\n", nbr++, data, (long long)GST_BUFFER_DURATION(buffer), buffer); - * gst_buffer_unref (buffer); - * } - * - * - * static void handoff (GstElement* object, - * GstBuffer* arg0, - * GstPad* arg1, - * gpointer user_data) - * { - * Ecore_Pipe *pipe; - * - * pipe = (Ecore_Pipe *)user_data; - * printf ("handoff : %p\n", arg0); - * gst_buffer_ref (arg0); - * ecore_pipe_write(pipe, &arg0, sizeof(arg0)); - * } - * - * int - * main (int argc, char *argv[]) - * { - * GstElement *pipeline; - * char *filename; - * Ecore_Pipe *pipe; - * - * gst_init (&argc, &argv); - * - * if (!ecore_init ()) - * { - * gst_deinit (); - * return 0; - * } - * - * pipe = ecore_pipe_add (handler); - * if (!pipe) - * { - * ecore_shutdown (); - * gst_deinit (); - * return 0; - * } - * - * if (argc < 2) { - * g_print ("usage: %s file.avi\n", argv[0]); - * ecore_pipe_del (pipe); - * ecore_shutdown (); - * gst_deinit (); - * return 0; - * } - * filename = argv[1]; - * - * pipeline = _buid_pipeline (filename, pipe); - * if (!pipeline) { - * g_print ("Error during the pipeline building\n"); - * ecore_pipe_del (pipe); - * ecore_shutdown (); - * gst_deinit (); - * return -1; - * } - * - * gst_element_set_state (pipeline, GST_STATE_PLAYING); - * - * ecore_main_loop_begin(); - * - * ecore_pipe_del (pipe); - * ecore_shutdown (); - * gst_deinit (); - * - * return 0; - * } - * - * static void - * new_decoded_pad_cb (GstElement *demuxer, - * GstPad *new_pad, - * gpointer user_data) - * { - * GstElement *decoder; - * GstPad *pad; - * GstCaps *caps; - * gchar *str; - * - * caps = gst_pad_get_caps (new_pad); - * str = gst_caps_to_string (caps); - * - * if (g_str_has_prefix (str, "video/")) { - * decoder = GST_ELEMENT (user_data); - * - * pad = gst_element_get_pad (decoder, "sink"); - * if (GST_PAD_LINK_FAILED (gst_pad_link (new_pad, pad))) { - * g_warning ("Failed to link %s:%s to %s:%s", GST_DEBUG_PAD_NAME (new_pad), - * GST_DEBUG_PAD_NAME (pad)); - * } - * } - * g_free (str); - * gst_caps_unref (caps); - * } - * - * static GstElement * - * _buid_pipeline (gchar *filename, Ecore_Pipe *pipe) - * { - * GstElement *pipeline; - * GstElement *filesrc; - * GstElement *demuxer; - * GstElement *decoder; - * GstElement *sink; - GstStateChangeReturn res; - * - * pipeline = gst_pipeline_new ("pipeline"); - * if (!pipeline) - * return NULL; - * - * filesrc = gst_element_factory_make ("filesrc", "filesrc"); - * if (!filesrc) { - * printf ("no filesrc"); - * goto failure; - * } - * g_object_set (G_OBJECT (filesrc), "location", filename, NULL); - * - * demuxer = gst_element_factory_make ("oggdemux", "demuxer"); - * if (!demuxer) { - * printf ("no demux"); - * goto failure; - * } - * - * decoder = gst_element_factory_make ("theoradec", "decoder"); - * if (!decoder) { - * printf ("no dec"); - * goto failure; - * } - * - * g_signal_connect (demuxer, "pad-added", - * G_CALLBACK (new_decoded_pad_cb), decoder); - * - * sink = gst_element_factory_make ("fakesink", "sink"); - * if (!sink) { - * printf ("no sink"); - * goto failure; - * } - * g_object_set (G_OBJECT (sink), "sync", EINA_TRUE, NULL); - * g_object_set (G_OBJECT (sink), "signal-handoffs", EINA_TRUE, NULL); - * g_signal_connect (sink, "handoff", - * G_CALLBACK (handoff), pipe); - * - * gst_bin_add_many (GST_BIN (pipeline), - * filesrc, demuxer, decoder, sink, NULL); - * - * if (!gst_element_link (filesrc, demuxer)) - * goto failure; - * if (!gst_element_link (decoder, sink)) - * goto failure; - * - * res = gst_element_set_state (pipeline, GST_STATE_PAUSED); - * if (res == GST_STATE_CHANGE_FAILURE) - * goto failure; - * - * res = gst_element_get_state( pipeline, NULL, NULL, GST_CLOCK_TIME_NONE ); - * if (res != GST_STATE_CHANGE_SUCCESS) - * goto failure; - * - * return pipeline; - * - * failure: - * gst_object_unref (GST_OBJECT (pipeline)); - * return NULL; - * } - * @endcode - */ - - -/** - * Create two file descriptors (sockets on Windows). Add - * a callback that will be called when the file descriptor that - * is listened receives data. An event is also put in the event - * queue when data is received. - * - * @param handler The handler called when data is received. - * @param data Data to pass to @p handler when it is called. - * @return A newly created Ecore_Pipe object if successful. - * @c NULL otherwise. - * @ingroup Ecore_Pipe_Group - */ -EAPI Ecore_Pipe *ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data) -{ - Ecore_Pipe *p; - int fds[2]; - - if (!handler) - return NULL; - - p = (Ecore_Pipe *) calloc(1, sizeof(Ecore_Pipe)); - if (!p) - return NULL; - - if (pipe(fds)) { - free(p); - return NULL; - } - - ECORE_MAGIC_SET(p, ECORE_MAGIC_PIPE); - p->fd_read = fds[0]; - p->fd_write = fds[1]; - p->handler = handler; - p->data = data; - - fcntl(p->fd_read, F_SETFL, O_NONBLOCK); - p->fd_handler = ecore_main_fd_handler_add(p->fd_read, - ECORE_FD_READ, - _ecore_pipe_read, - p, NULL, NULL); - return p; -} - -/** - * Free an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object to be freed. - * @return The pointer to the private data - * @ingroup Ecore_Pipe_Group - */ -EAPI void *ecore_pipe_del(Ecore_Pipe * p) -{ - void *data; - - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del"); - return NULL; - } - if (p->fd_handler) - ecore_main_fd_handler_del(p->fd_handler); - if (p->fd_read != PIPE_FD_INVALID) - pipe_close(p->fd_read); - if (p->fd_write != PIPE_FD_INVALID) - pipe_close(p->fd_write); - data = (void *) p->data; - free(p); - return data; -} - -/** - * Close the read end of an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object. - * @ingroup Ecore_Pipe_Group - */ -EAPI void ecore_pipe_read_close(Ecore_Pipe * p) -{ - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, - "ecore_pipe_read_close"); - return; - } - ecore_main_fd_handler_del(p->fd_handler); - p->fd_handler = NULL; - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; -} - -/** - * Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object. - * @ingroup Ecore_Pipe_Group - */ -EAPI void ecore_pipe_write_close(Ecore_Pipe * p) -{ - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, - "ecore_pipe_write_close"); - return; - } - pipe_close(p->fd_write); - p->fd_write = PIPE_FD_INVALID; -} - -/** - * Write on the file descriptor the data passed as parameter. - * - * @param p The Ecore_Pipe object. - * @param buffer The data to write into the pipe. - * @param nbytes The size of the @p buffer in bytes - * @return Returns EINA_TRUE on a successful write, EINA_FALSE on an error - * @ingroup Ecore_Pipe_Group - */ -EAPI Eina_Bool -ecore_pipe_write(Ecore_Pipe * p, const void *buffer, unsigned int nbytes) -{ - ssize_t ret; - size_t already_written = 0; - int retry = ECORE_PIPE_WRITE_RETRY; - - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write"); - return EINA_FALSE; - } - - if (p->fd_write == PIPE_FD_INVALID) - return EINA_FALSE; - - /* First write the len into the pipe */ - do { - ret = pipe_write(p->fd_write, &nbytes, sizeof(nbytes)); - if (ret == sizeof(nbytes)) { - retry = ECORE_PIPE_WRITE_RETRY; - break; - } else if (ret > 0) { - /* XXX What should we do here? */ - ERR("The length of the data was not written complete" " to the pipe"); - return EINA_FALSE; - } else if (ret == PIPE_FD_ERROR && errno == EPIPE) { - pipe_close(p->fd_write); - p->fd_write = PIPE_FD_INVALID; - return EINA_FALSE; - } else if (ret == PIPE_FD_ERROR && errno == EINTR) - /* try it again */ - ; - else { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while writing to the pipe the length", - ret, errno); - } - } - while (retry--); - - if (retry != ECORE_PIPE_WRITE_RETRY) - return EINA_FALSE; - - /* and now pass the data to the pipe */ - do { - ret = pipe_write(p->fd_write, - ((unsigned char *) buffer) + - already_written, - nbytes - already_written); - - if (ret == (ssize_t) (nbytes - already_written)) - return EINA_TRUE; - else if (ret >= 0) { - already_written -= ret; - continue; - } else if (ret == PIPE_FD_ERROR && errno == EPIPE) { - pipe_close(p->fd_write); - p->fd_write = PIPE_FD_INVALID; - return EINA_FALSE; - } else if (ret == PIPE_FD_ERROR && errno == EINTR) - /* try it again */ - ; - else { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while writing to the pipe the length", - ret, errno); - } - } - while (retry--); - - return EINA_FALSE; -} - -/* Private function */ - -static Eina_Bool -_ecore_pipe_read(void *data, Ecore_Fd_Handler * fd_handler __UNUSED__) -{ - Ecore_Pipe *p; - double start_time; - - p = (Ecore_Pipe *) data; - start_time = ecore_time_get(); - - do { - ssize_t ret; - - /* if we already have read some data we don't need to read the len - * but to finish the already started job - */ - if (p->len == 0) { - /* read the len of the passed data */ - ret = - pipe_read(p->fd_read, &p->len, sizeof(p->len)); - - /* catch the non error case first */ - if (ret == sizeof(p->len)); - else if (ret > 0) { - /* XXX What should we do here? */ - ERR("Only read %zd bytes from the pipe, although" " we need to read %zd bytes.", ret, sizeof(p->len)); - } else if (ret == 0) { - p->handler((void *) p->data, NULL, 0); - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - return ECORE_CALLBACK_CANCEL; - } -#ifndef _WIN32 - else if ((ret == PIPE_FD_ERROR) - && ((errno == EINTR) - || (errno == EAGAIN))) - return ECORE_CALLBACK_RENEW; - else { - ERR("An unhandled error (ret: %zd errno: %d)" "occurred while reading from the pipe the length", ret, errno); - return ECORE_CALLBACK_RENEW; - } -#else - else { /* ret == PIPE_FD_ERROR is the only other case on Windows */ - - if (WSAGetLastError() != WSAEWOULDBLOCK) { - p->handler((void *) p->data, NULL, - 0); - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - return ECORE_CALLBACK_CANCEL; - } - } -#endif - } - - if (!p->passed_data) - p->passed_data = malloc(p->len); - - /* and read the passed data */ - ret = pipe_read(p->fd_read, - ((unsigned char *) p->passed_data) + - p->already_read, p->len - p->already_read); - - /* catch the non error case first */ - if (ret == (ssize_t) (p->len - p->already_read)) { - p->handler((void *) p->data, p->passed_data, - p->len); - free(p->passed_data); - /* reset all values to 0 */ - p->passed_data = NULL; - p->already_read = 0; - p->len = 0; - } else if (ret >= 0) { - p->already_read += ret; - return ECORE_CALLBACK_RENEW; - } else if (ret == 0) { - p->handler((void *) p->data, NULL, 0); - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - return ECORE_CALLBACK_CANCEL; - } -#ifndef _WIN32 - else if (ret == PIPE_FD_ERROR - && (errno == EINTR || errno == EAGAIN)) - return ECORE_CALLBACK_RENEW; - else { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while reading from the pipe the data", - ret, errno); - return ECORE_CALLBACK_RENEW; - } -#else - else { /* ret == PIPE_FD_ERROR is the only other case on Windows */ - - if (WSAGetLastError() != WSAEWOULDBLOCK) { - p->handler((void *) p->data, NULL, 0); - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - return ECORE_CALLBACK_CANCEL; - } else - break; - } -#endif - } - while (ecore_time_get() - start_time < - ecore_animator_frametime_get()); - - return ECORE_CALLBACK_RENEW; -} diff --git a/tests/suite/ecore/src/lib/ecore_poll.c b/tests/suite/ecore/src/lib/ecore_poll.c deleted file mode 100644 index 0c3c208692..0000000000 --- a/tests/suite/ecore/src/lib/ecore_poll.c +++ /dev/null @@ -1,446 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#include "Ecore.h" -#include "ecore_private.h" - - -struct _Ecore_Poller { - EINA_INLIST; - ECORE_MAGIC; - int ibit; - unsigned char delete_me:1; - Ecore_Task_Cb func; - void *data; -}; - - -static Ecore_Timer *timer = NULL; -static int min_interval = -1; -static int interval_incr = 0; -static int at_tick = 0; -static int just_added_poller = 0; -static int poller_delete_count = 0; -static int poller_walking = 0; -static double poll_interval = 0.125; -static double poll_cur_interval = 0.0; -static double last_tick = 0.0; -static Ecore_Poller *pollers[16] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -static unsigned short poller_counters[16] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static void _ecore_poller_next_tick_eval(void); -static Eina_Bool _ecore_poller_cb_timer(void *data); - -static void _ecore_poller_next_tick_eval(void) -{ - int i; - double interval; - - min_interval = -1; - for (i = 0; i < 15; i++) { - if (pollers[i]) { - min_interval = i; - break; - } - } - if (min_interval < 0) { - /* no pollers */ - if (timer) { - ecore_timer_del(timer); - timer = NULL; - } - return; - } - interval_incr = (1 << min_interval); - interval = interval_incr * poll_interval; - /* we are at the tick callback - so no need to do inter-tick adjustments - * so we can fasttrack this as t -= last_tick in theory is 0.0 (though - * in practice it will be a very very very small value. also the tick - * callback will adjust the timer interval at the end anyway */ - if (at_tick) { - if (!timer) - timer = - ecore_timer_add(interval, - _ecore_poller_cb_timer, NULL); - } else { - double t; - - if (!timer) - timer = - ecore_timer_add(interval, - _ecore_poller_cb_timer, NULL); - else { - t = ecore_time_get(); - if (interval != poll_cur_interval) { - t -= last_tick; /* time since we last ticked */ - /* delete the timer and reset it to tick off in the new - * time interval. at the tick this will be adjusted */ - ecore_timer_del(timer); - timer = ecore_timer_add(interval - t, - _ecore_poller_cb_timer, - NULL); - } - } - } - poll_cur_interval = interval; -} - -static Eina_Bool _ecore_poller_cb_timer(void *data __UNUSED__) -{ - int i; - Ecore_Poller *poller, *l; - int changes = 0; - - at_tick++; - last_tick = ecore_time_get(); - /* we have 16 counters - each incriments every time the poller counter - * "ticks". it incriments by the minimum interval (which can be 1, 2, 4, - * 7, 16 etc. up to 32768) */ - for (i = 0; i < 15; i++) { - poller_counters[i] += interval_incr; - /* wrap back to 0 if we exceed out loop count for the counter */ - if (poller_counters[i] >= (1 << i)) - poller_counters[i] = 0; - } - - just_added_poller = 0; - /* walk the pollers now */ - poller_walking++; - for (i = 0; i < 15; i++) { - /* if the counter is @ 0 - this means that counter "went off" this - * tick interval, so run all pollers hooked to that counter */ - if (poller_counters[i] == 0) { - EINA_INLIST_FOREACH(pollers[i], poller) { - if (!poller->delete_me) { - if (!poller->func(poller->data)) { - if (!poller->delete_me) { - poller->delete_me = - 1; - poller_delete_count++; - } - } - } - } - } - } - poller_walking--; - - /* handle deletes afterwards */ - if (poller_delete_count > 0) { - /* FIXME: walk all pollers and remove deleted ones */ - for (i = 0; i < 15; i++) { - for (l = pollers[i]; l;) { - poller = l; - l = (Ecore_Poller *) EINA_INLIST_GET(l)-> - next; - if (poller->delete_me) { - pollers[i] = - (Ecore_Poller *) - eina_inlist_remove - (EINA_INLIST_GET(pollers[i]), - EINA_INLIST_GET(poller)); - free(poller); - poller_delete_count--; - changes++; - if (poller_delete_count <= 0) - break; - } - } - if (poller_delete_count <= 0) - break; - } - } - /* if we deleted or added any pollers, then we need to re-evaluate our - * minimum poll interval */ - if ((changes > 0) || (just_added_poller > 0)) - _ecore_poller_next_tick_eval(); - - just_added_poller = 0; - poller_delete_count = 0; - - at_tick--; - - /* if the timer was deleted then there is no point returning 1 - ambiguous - * if we do as it im plies "keep running me" but we have been deleted - * anyway */ - if (!timer) - return ECORE_CALLBACK_CANCEL; - - /* adjust interval */ - ecore_timer_interval_set(timer, poll_cur_interval); - return ECORE_CALLBACK_RENEW; -} - -/** - * @defgroup Ecore_Poll_Group Ecore Poll Functions - * - * These functions are for the need to poll information, but provide a shared - * abstracted API to pool such polling to minimise wakeup and ensure all the - * polling happens in as few spots as possible areound a core poll interval. - * For now only 1 core poller type is supprted: ECORE_POLLER_CORE - */ - - -/** - * Sets the time between ticks (in seconds) for the given ticker clock. - * @param type The ticker type to adjust - * @param poll_time The time (in seconds) between ticks of the clock - * @ingroup Ecore_Poller_Group - * - * This will adjust the time between ticks of the given ticker type defined - * by @p type to the time period defined by @p poll_time. - */ -EAPI void -ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__, - double poll_time) -{ - poll_interval = poll_time; - _ecore_poller_next_tick_eval(); -} - -/** - * Gets the time between ticks (in seconds) for the given ticker clock. - * @param type The ticker type to query - * @return The time in seconds between ticks of the ticker clock - * @ingroup Ecore_Poller_Group - * - * This will get the time between ticks of the specifider ticker clock. - */ -EAPI double -ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__) -{ - return poll_interval; -} - -/** - * Creates a poller to call the given function at a particular tick interval. - * @param type The ticker type to attach the poller to - * @param interval The poll interval - * @param func The given function. If @p func returns 1, the poller is - * rescheduled for the next tick interval. - * @param data Data to pass to @p func when it is called. - * @return A poller object on success. @c NULL on failure. - * @ingroup Ecore_Poller_Group - * - * This function adds a poller callback that is to be called regularly - * along with all other poller callbacks so the pollers are synchronized with - * all other pollers running off the same poller type and at the same tick - * interval. This should be used for polling things when polling is desired - * or required, and you do not have specific requirements on the exact times - * to poll and want to avoid extra process wakeups for polling. This will - * save power as the CPU has more of a chance to go into a low power state - * the longer it is asleep for, so this should be used if you are at all - * power conscious. - * - * The @p type parameter defines the poller tick type (there is a virtual - * clock ticking all the time - though ecore avoids making it tick when - * there will not be any work to do at that tick point). There is only one - * ticker at the moment - that is ECORE_POLLER_CORE. This is here for future - * expansion if multiple clocks with different frequencies are really required. - * The default time between ticks for the ECORE_POLLER_CORE ticker is 0.125 - * seconds. - * - * The @p interval is the number of ticker ticks that will pass by in between - * invocations of the @p func callback. This must be between 1 and 32768 - * inclusive, and must be a power of 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768). - * If it is 1, then the function will be called every tick. if it is 2, then it - * will be called every 2nd tick, if it is 8, then every 8th tick etc. Exactly - * which tick is undefined, as only the interval between calls can be defined. - * Ecore will endeavour to keep pollers synchronised and to call as many in - * 1 wakeup event as possible. - * - * This function adds a poller and returns its handle on success and NULL on - * failure. The function @p func will be called at tick intervals described - * above. The function will be passed the @p data pointer as its parameter. - * - * When the poller @p func is called, it must return a value of either - * 1 (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL). If it - * returns 1, it will be called again at the next tick, or if it returns - * 0 it will be deleted automatically making any references/handles for it - * invalid. - */ -EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type __UNUSED__, - int interval, Ecore_Task_Cb func, - const void *data) -{ - Ecore_Poller *poller; - int ibit; - - if (!func) - return NULL; - if (interval < 1) - interval = 1; - - poller = calloc(1, sizeof(Ecore_Poller)); - if (!poller) - return NULL; - ECORE_MAGIC_SET(poller, ECORE_MAGIC_POLLER); - /* interval MUST be a power of 2, so enforce it */ - if (interval < 1) - interval = 1; - ibit = -1; - while (interval != 0) { - ibit++; - interval >>= 1; - } - /* only allow up to 32768 - i.e. ibit == 15, so limit it */ - if (ibit > 15) - ibit = 15; - - poller->ibit = ibit; - poller->func = func; - poller->data = (void *) data; - pollers[poller->ibit] = - (Ecore_Poller *) - eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), - EINA_INLIST_GET(poller)); - if (poller_walking) - just_added_poller++; - else - _ecore_poller_next_tick_eval(); - return poller; -} - -/** - * Changes the polling interval rate of @p poller. - * - * @param poller The Ecore_Poller to change the interval of - * @param interval The tick interval to set; must be a power of 2 but <= 32768 - * @return Returns true on success, false on failure - * - * This allows the changing of a poller's polling interval. It is useful when you want to alter - * a poll rate without deleting and re-creating a poller. - * @ingroup Ecore_Poller_Group - */ -EAPI Eina_Bool -ecore_poller_poller_interval_set(Ecore_Poller * poller, int interval) -{ - int ibit; - - if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER)) { - ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER, - "ecore_poller_poller_interval_set"); - return EINA_FALSE; - } - - /* interval MUST be a power of 2, so enforce it */ - if (interval < 1) - interval = 1; - ibit = -1; - while (interval != 0) { - ibit++; - interval >>= 1; - } - /* only allow up to 32768 - i.e. ibit == 15, so limit it */ - if (ibit > 15) - ibit = 15; - /* if interval specified is the same as interval set, return true without wasting time */ - if (poller->ibit == ibit) - return EINA_TRUE; - pollers[poller->ibit] = - (Ecore_Poller *) - eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), - EINA_INLIST_GET(poller)); - poller->ibit = ibit; - pollers[poller->ibit] = - (Ecore_Poller *) - eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), - EINA_INLIST_GET(poller)); - if (poller_walking) - just_added_poller++; - else - _ecore_poller_next_tick_eval(); - return EINA_TRUE; -} - -/** - * Gets the polling interval rate of @p poller. - * - * @param poller The Ecore_Poller to change the interval of - * @return Returns the interval, in ticks, that @p poller polls at - * - * This returns a poller's polling interval, or 0 on error. - * @ingroup Ecore_Poller_Group - */ -EAPI int ecore_poller_poller_interval_get(Ecore_Poller * poller) -{ - int ibit, interval = 1; - - if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER)) { - ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER, - "ecore_poller_poller_interval_get"); - return 0; - } - - ibit = poller->ibit; - while (ibit != 0) { - ibit--; - interval <<= 1; - } - return interval; -} - -/** - * Delete the specified poller from the timer list. - * @param poller The poller to delete. - * @return The data pointer set for the timer when @ref ecore_poller_add was - * called. @c NULL is returned if the function is unsuccessful. - * @ingroup Ecore_Poller_Group - * - * Note: @p poller must be a valid handle. If the poller function has already - * returned 0, the handle is no longer valid (and does not need to be delete). - */ -EAPI void *ecore_poller_del(Ecore_Poller * poller) -{ - void *data; - - if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER)) { - ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER, - "ecore_poller_del"); - return NULL; - } - /* we are walking the poller list - a bad idea to remove from it while - * walking it, so just flag it as delete_me and come back to it after - * the loop has finished */ - if (poller_walking > 0) { - poller_delete_count++; - poller->delete_me = 1; - return poller->data; - } - /* not in loop so safe - delete immediately */ - data = poller->data; - pollers[poller->ibit] = - (Ecore_Poller *) - eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), - EINA_INLIST_GET(poller)); - free(poller); - _ecore_poller_next_tick_eval(); - return data; -} - -void _ecore_poller_shutdown(void) -{ - int i; - Ecore_Poller *poller; - - for (i = 0; i < 15; i++) { - while ((poller = pollers[i])) { - pollers[i] = - (Ecore_Poller *) - eina_inlist_remove(EINA_INLIST_GET(pollers[i]), - EINA_INLIST_GET(pollers - [i])); - free(poller); - } - } -} diff --git a/tests/suite/ecore/src/lib/ecore_private.h b/tests/suite/ecore/src/lib/ecore_private.h deleted file mode 100644 index d487739679..0000000000 --- a/tests/suite/ecore/src/lib/ecore_private.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef _ECORE_PRIVATE_H -#define _ECORE_PRIVATE_H - -extern int _ecore_log_dom; -#ifdef _ECORE_DEFAULT_LOG_DOM -#undef _ECORE_DEFAULT_LOG_DOM -#endif -#define _ECORE_DEFAULT_LOG_DOM _ecore_log_dom - -#ifdef ECORE_DEFAULT_LOG_COLOR -#undef ECORE_DEFAULT_LOG_COLOR -#endif -#define ECORE_DEFAULT_LOG_COLOR EINA_COLOR_BLUE - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__) - -#ifdef INF -#undef INF -#endif -#define INF(...) EINA_LOG_DOM_INFO(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__) - -#ifdef WRN -#undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__) - -#ifdef CRIT -#undef CRIT -#endif -#define CRIT(...) EINA_LOG_DOM_CRIT(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__) - -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - -#ifndef MIN -#define MIN(x, y) (((x) > (y)) ? (y) : (x)) -#endif - -#ifndef MAX -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) -#endif - -#ifndef ABS -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#endif - -#ifndef CLAMP -#define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x))) -#endif - -#define EVAS_FRAME_QUEUING 1 /* for test */ - -#define READBUFSIZ 65536 - -#define ECORE_MAGIC_NONE 0x1234fedc -#define ECORE_MAGIC_EXE 0xf7e812f5 -#define ECORE_MAGIC_TIMER 0xf7d713f4 -#define ECORE_MAGIC_IDLER 0xf7c614f3 -#define ECORE_MAGIC_IDLE_ENTERER 0xf7b515f2 -#define ECORE_MAGIC_IDLE_EXITER 0xf7601afd -#define ECORE_MAGIC_FD_HANDLER 0xf7a416f1 -#define ECORE_MAGIC_EVENT_HANDLER 0xf79317f0 -#define ECORE_MAGIC_EVENT_FILTER 0xf78218ff -#define ECORE_MAGIC_EVENT 0xf77119fe -#define ECORE_MAGIC_ANIMATOR 0xf7643ea5 -#define ECORE_MAGIC_POLLER 0xf7568127 -#define ECORE_MAGIC_PIPE 0xf7458226 -#define ECORE_MAGIC_WIN32_HANDLER 0xf7e8f1a3 -#define ECORE_MAGIC_JOB 0x76543210 - - -#define ECORE_MAGIC Ecore_Magic __magic - -#define ECORE_MAGIC_SET(d, m) (d)->__magic = (m) -#define ECORE_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m))) -#define ECORE_MAGIC_FAIL(d, m, fn) _ecore_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn)); - -/* undef the following, we want our version */ -#undef FREE -#define FREE(ptr) free(ptr); ptr = NULL; - -#undef IF_FREE -#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL; - -#undef IF_FN_DEL -#define IF_FN_DEL(_fn, ptr) if (ptr) { _fn(ptr); ptr = NULL; } - -EAPI void ecore_print_warning(const char *function, const char *sparam); - -/* convenience macros for checking pointer parameters for non-NULL */ -#undef CHECK_PARAM_POINTER_RETURN -#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \ - if (!(param)) \ - { \ - ecore_print_warning(__FUNCTION__, sparam); \ - return ret; \ - } - -#undef CHECK_PARAM_POINTER -#define CHECK_PARAM_POINTER(sparam, param) \ - if (!(param)) \ - { \ - ecore_print_warning(__FUNCTION__, sparam); \ - return; \ - } - -typedef unsigned int Ecore_Magic; - -EAPI void _ecore_magic_fail(const void *d, Ecore_Magic m, - Ecore_Magic req_m, const char *fname); - -void _ecore_time_init(void); - -void _ecore_timer_shutdown(void); -void _ecore_timer_cleanup(void); -void _ecore_timer_enable_new(void); -double _ecore_timer_next_get(void); -int _ecore_timers_exists(void); -int _ecore_timer_call(double when); - -void _ecore_idler_shutdown(void); -int _ecore_idler_call(void); -int _ecore_idler_exist(void); - -void _ecore_idle_enterer_shutdown(void); -void _ecore_idle_enterer_call(void); -int _ecore_idle_enterer_exist(void); - -void _ecore_idle_exiter_shutdown(void); -void _ecore_idle_exiter_call(void); -int _ecore_idle_exiter_exist(void); - -void _ecore_event_shutdown(void); -int _ecore_event_exist(void); -Ecore_Event *_ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, - void *data); -void _ecore_event_call(void); - -Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe * exe); -void _ecore_exe_doomsday_clock_set(Ecore_Exe * exe, Ecore_Timer * dc); - -EAPI void *_ecore_event_signal_user_new(void); -void *_ecore_event_signal_hup_new(void); -void *_ecore_event_signal_exit_new(void); -void *_ecore_event_signal_power_new(void); -void *_ecore_event_signal_realtime_new(void); - -void _ecore_main_shutdown(void); - -#ifdef _WIN32 -static inline void _ecore_signal_shutdown(void) -{ -} - -static inline void _ecore_signal_init(void) -{ -} - -static inline int _ecore_signal_count_get(void) -{ - return 0; -} - -static inline void _ecore_signal_call(void) -{ -} -#else -void _ecore_signal_shutdown(void); -void _ecore_signal_init(void); -int _ecore_signal_count_get(void); -void _ecore_signal_call(void); -#endif - -void _ecore_exe_init(void); -void _ecore_exe_shutdown(void); -#ifndef _WIN32 -Ecore_Exe *_ecore_exe_find(pid_t pid); -void *_ecore_exe_event_del_new(void); -void _ecore_exe_event_del_free(void *data, void *ev); -#endif - -void _ecore_animator_shutdown(void); - -void _ecore_poller_shutdown(void); - -EAPI void *_ecore_list2_append(void *in_list, void *in_item); -EAPI void *_ecore_list2_prepend(void *in_list, void *in_item); -EAPI void *_ecore_list2_append_relative(void *in_list, void *in_item, - void *in_relative); -EAPI void *_ecore_list2_prepend_relative(void *in_list, void *in_item, - void *in_relative); -EAPI void *_ecore_list2_remove(void *in_list, void *in_item); -EAPI void *_ecore_list2_find(void *in_list, void *in_item); - -void _ecore_fps_debug_init(void); -void _ecore_fps_debug_shutdown(void); -void _ecore_fps_debug_runtime_add(double t); - -void _ecore_thread_init(void); -void _ecore_thread_shutdown(void); - -void _ecore_glib_init(void); -void _ecore_glib_shutdown(void); - -void _ecore_job_init(void); -void _ecore_job_shutdown(void); - -void _ecore_main_loop_init(void); -void _ecore_main_loop_shutdown(void); - -extern int _ecore_fps_debug; -extern double _ecore_time_loop_time; -extern Eina_Bool _ecore_glib_always_integrate; - -#endif diff --git a/tests/suite/ecore/src/lib/ecore_signal.c b/tests/suite/ecore/src/lib/ecore_signal.c deleted file mode 100644 index a3ef01e53a..0000000000 --- a/tests/suite/ecore/src/lib/ecore_signal.c +++ /dev/null @@ -1,624 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> -#include <assert.h> - -#include "Ecore.h" -#include "ecore_private.h" - -/* make mono happy - this is evil though... */ -#undef SIGPWR -/* valgrind in some versions/setups uses SIGRT's... hmmm */ -#undef SIGRTMIN - -typedef void (*Signal_Handler) (int sig, siginfo_t * si, void *foo); - -static void _ecore_signal_callback_set(int sig, Signal_Handler func); -static void _ecore_signal_callback_ignore(int sig, siginfo_t * si, - void *foo); -static void _ecore_signal_callback_sigchld(int sig, siginfo_t * si, - void *foo); -static void _ecore_signal_callback_sigusr1(int sig, siginfo_t * si, - void *foo); -static void _ecore_signal_callback_sigusr2(int sig, siginfo_t * si, - void *foo); -static void _ecore_signal_callback_sighup(int sig, siginfo_t * si, - void *foo); -static void _ecore_signal_callback_sigquit(int sig, siginfo_t * si, - void *foo); -static void _ecore_signal_callback_sigint(int sig, siginfo_t * si, - void *foo); -static void _ecore_signal_callback_sigterm(int sig, siginfo_t * si, - void *foo); -#ifdef SIGPWR -static void _ecore_signal_callback_sigpwr(int sig, siginfo_t * si, - void *foo); -#endif - -#ifdef SIGRTMIN -static void _ecore_signal_callback_sigrt(int sig, siginfo_t * si, - void *foo); -#endif - -static Eina_Bool _ecore_signal_exe_exit_delay(void *data); - -//#define MAXSIGQ 256 // 32k -#define MAXSIGQ 64 // 8k - -static volatile sig_atomic_t sig_count = 0; -static volatile sig_atomic_t sigchld_count = 0; -static volatile sig_atomic_t sigusr1_count = 0; -static volatile sig_atomic_t sigusr2_count = 0; -static volatile sig_atomic_t sighup_count = 0; -static volatile sig_atomic_t sigquit_count = 0; -static volatile sig_atomic_t sigint_count = 0; -static volatile sig_atomic_t sigterm_count = 0; -#ifdef SIGPWR -static volatile sig_atomic_t sigpwr_count = 0; -#endif -#ifdef SIGRTMIN -static volatile sig_atomic_t *sigrt_count = NULL; -#endif - -static volatile siginfo_t sigchld_info[MAXSIGQ]; -static volatile siginfo_t sigusr1_info[MAXSIGQ]; -static volatile siginfo_t sigusr2_info[MAXSIGQ]; -static volatile siginfo_t sighup_info[MAXSIGQ]; -static volatile siginfo_t sigquit_info[MAXSIGQ]; -static volatile siginfo_t sigint_info[MAXSIGQ]; -static volatile siginfo_t sigterm_info[MAXSIGQ]; -#ifdef SIGPWR -static volatile siginfo_t sigpwr_info[MAXSIGQ]; -#endif -#ifdef SIGRTMIN -static volatile siginfo_t *sigrt_info[MAXSIGQ]; -#endif - -void _ecore_signal_shutdown(void) -{ -#ifdef SIGRTMIN - int i, num = SIGRTMAX - SIGRTMIN; -#endif - - _ecore_signal_callback_set(SIGPIPE, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGALRM, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGCHLD, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGUSR1, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGUSR2, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGHUP, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGQUIT, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGINT, (Signal_Handler) SIG_DFL); - _ecore_signal_callback_set(SIGTERM, (Signal_Handler) SIG_DFL); -#ifdef SIGPWR - _ecore_signal_callback_set(SIGPWR, (Signal_Handler) SIG_DFL); - sigpwr_count = 0; -#endif - sigchld_count = 0; - sigusr1_count = 0; - sigusr2_count = 0; - sighup_count = 0; - sigquit_count = 0; - sigint_count = 0; - sigterm_count = 0; - sig_count = 0; - -#ifdef SIGRTMIN - for (i = 0; i < num; i++) { - _ecore_signal_callback_set(SIGRTMIN + i, - (Signal_Handler) SIG_DFL); - sigrt_count[i] = 0; - } - - if (sigrt_count) { - free((sig_atomic_t *) sigrt_count); - sigrt_count = NULL; - } - - for (i = 0; i < MAXSIGQ; i++) { - if (sigrt_info[i]) { - free((siginfo_t *) sigrt_info[i]); - sigrt_info[i] = NULL; - } - } -#endif -} - -void _ecore_signal_init(void) -{ -#ifdef SIGRTMIN - int i, num = SIGRTMAX - SIGRTMIN; -#endif - - _ecore_signal_callback_set(SIGPIPE, _ecore_signal_callback_ignore); - _ecore_signal_callback_set(SIGALRM, _ecore_signal_callback_ignore); - _ecore_signal_callback_set(SIGCHLD, - _ecore_signal_callback_sigchld); - _ecore_signal_callback_set(SIGUSR1, - _ecore_signal_callback_sigusr1); - _ecore_signal_callback_set(SIGUSR2, - _ecore_signal_callback_sigusr2); - _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup); - _ecore_signal_callback_set(SIGQUIT, - _ecore_signal_callback_sigquit); - _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint); - _ecore_signal_callback_set(SIGTERM, - _ecore_signal_callback_sigterm); -#ifdef SIGPWR - _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr); -#endif - -#ifdef SIGRTMIN - sigrt_count = calloc(1, sizeof(sig_atomic_t) * num); - assert(sigrt_count); - - for (i = 0; i < MAXSIGQ; i++) { - sigrt_info[i] = calloc(1, sizeof(siginfo_t) * num); - assert(sigrt_info[i]); - } - - for (i = 0; i < num; i++) - _ecore_signal_callback_set(SIGRTMIN + i, - _ecore_signal_callback_sigrt); -#endif -} - -int _ecore_signal_count_get(void) -{ - return sig_count; -} - -void _ecore_signal_call(void) -{ -#ifdef SIGRTMIN - int i, num = SIGRTMAX - SIGRTMIN; -#endif - volatile sig_atomic_t n; - sigset_t oldset, newset; - - if (sig_count == 0) - return; - sigemptyset(&newset); - sigaddset(&newset, SIGPIPE); - sigaddset(&newset, SIGALRM); - sigaddset(&newset, SIGCHLD); - sigaddset(&newset, SIGUSR1); - sigaddset(&newset, SIGUSR2); - sigaddset(&newset, SIGHUP); - sigaddset(&newset, SIGQUIT); - sigaddset(&newset, SIGINT); - sigaddset(&newset, SIGTERM); -#ifdef SIGPWR - sigaddset(&newset, SIGPWR); -#endif -#ifdef SIGRTMIN - for (i = 0; i < num; i++) - sigaddset(&newset, SIGRTMIN + i); -#endif - sigprocmask(SIG_BLOCK, &newset, &oldset); - if (sigchld_count > MAXSIGQ) - WRN("%i SIGCHLD in queue. max queue size %i. losing " - "siginfo for extra signals.", sigchld_count, MAXSIGQ); - for (n = 0; n < sigchld_count; n++) { - pid_t pid; - int status; - - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { - Ecore_Exe_Event_Del *e; - - /* FIXME: If this process is set respawn, respawn with a suitable backoff - * period for those that need too much respawning. - */ - e = _ecore_exe_event_del_new(); - if (e) { - if (WIFEXITED(status)) { - e->exit_code = WEXITSTATUS(status); - e->exited = 1; - } else if (WIFSIGNALED(status)) { - e->exit_signal = WTERMSIG(status); - e->signalled = 1; - } - e->pid = pid; - e->exe = _ecore_exe_find(pid); - - if ((n < MAXSIGQ) - && (sigchld_info[n].si_signo)) - e->data = sigchld_info[n]; /* No need to clone this. */ - - if ((e->exe) - && (ecore_exe_flags_get(e->exe) & - (ECORE_EXE_PIPE_READ | - ECORE_EXE_PIPE_ERROR))) { - /* We want to report the Last Words of the exe, so delay this event. - * This is twice as relevant for stderr. - * There are three possibilities here - - * 1 There are no Last Words. - * 2 There are Last Words, they are not ready to be read. - * 3 There are Last Words, they are ready to be read. - * - * For 1 we don't want to delay, for 3 we want to delay. - * 2 is the problem. If we check for data now and there - * is none, then there is no way to differentiate 1 and 2. - * If we don't delay, we may loose data, but if we do delay, - * there may not be data and the exit event never gets sent. - * - * Any way you look at it, there has to be some time passed - * before the exit event gets sent. So the strategy here is - * to setup a timer event that will send the exit event after - * an arbitrary, but brief, time. - * - * This is probably paranoid, for the less paraniod, we could - * check to see for Last Words, and only delay if there are any. - * This has it's own set of problems. - */ - Ecore_Timer *doomsday_clock; - - doomsday_clock = - _ecore_exe_doomsday_clock_get - (e->exe); - IF_FN_DEL(ecore_timer_del, - doomsday_clock); - _ecore_exe_doomsday_clock_set(e-> - exe, - ecore_timer_add - (0.1, - _ecore_signal_exe_exit_delay, - e)); - } else { - _ecore_event_add - (ECORE_EXE_EVENT_DEL, e, - _ecore_exe_event_del_free, - NULL); - } - } - } - sig_count--; - } - sigchld_count = 0; - - if (sigusr1_count > MAXSIGQ) - WRN("%i SIGUSR1 in queue. max queue size %i. losing " - "siginfo for extra signals.", sigusr1_count, MAXSIGQ); - for (n = 0; n < sigusr1_count; n++) { - Ecore_Event_Signal_User *e; - - e = _ecore_event_signal_user_new(); - if (e) { - e->number = 1; - - if ((n < MAXSIGQ) && (sigusr1_info[n].si_signo)) - e->data = sigusr1_info[n]; - - ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, - NULL); - } - sig_count--; - } - sigusr1_count = 0; - - if (sigusr2_count > MAXSIGQ) - WRN("%i SIGUSR2 in queue. max queue size %i. losing " - "siginfo for extra signals.", sigusr2_count, MAXSIGQ); - for (n = 0; n < sigusr2_count; n++) { - Ecore_Event_Signal_User *e; - - e = _ecore_event_signal_user_new(); - if (e) { - e->number = 2; - - if ((n < MAXSIGQ) && (sigusr2_info[n].si_signo)) - e->data = sigusr2_info[n]; - - ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, - NULL); - } - sig_count--; - } - sigusr2_count = 0; - - if (sighup_count > MAXSIGQ) - WRN("%i SIGHUP in queue. max queue size %i. losing " - "siginfo for extra signals.", sighup_count, MAXSIGQ); - for (n = 0; n < sighup_count; n++) { - Ecore_Event_Signal_Hup *e; - - e = _ecore_event_signal_hup_new(); - if (e) { - if ((n < MAXSIGQ) && (sighup_info[n].si_signo)) - e->data = sighup_info[n]; - - ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e, NULL, - NULL); - } - sig_count--; - } - sighup_count = 0; - - if (sigquit_count > MAXSIGQ) - WRN("%i SIGQUIT in queue. max queue size %i. losing " - "siginfo for extra signals.", sigquit_count, MAXSIGQ); - for (n = 0; n < sigquit_count; n++) { - Ecore_Event_Signal_Exit *e; - - e = _ecore_event_signal_exit_new(); - if (e) { - e->quit = 1; - - if ((n < MAXSIGQ) && (sigquit_info[n].si_signo)) - e->data = sigquit_info[n]; - - ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, - NULL); - } - sig_count--; - } - sigquit_count = 0; - - if (sigint_count > MAXSIGQ) - WRN("%i SIGINT in queue. max queue size %i. losing " - "siginfo for extra signals.", sigint_count, MAXSIGQ); - for (n = 0; n < sigint_count; n++) { - Ecore_Event_Signal_Exit *e; - - e = _ecore_event_signal_exit_new(); - if (e) { - e->interrupt = 1; - - if ((n < MAXSIGQ) && (sigint_info[n].si_signo)) - e->data = sigint_info[n]; - - ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, - NULL); - } - sig_count--; - } - sigint_count = 0; - - if (sigterm_count > MAXSIGQ) - WRN("%i SIGTERM in queue. max queue size %i. losing " - "siginfo for extra signals.", sigterm_count, MAXSIGQ); - for (n = 0; n < sigterm_count; n++) { - Ecore_Event_Signal_Exit *e; - - e = _ecore_event_signal_exit_new(); - if (e) { - e->terminate = 1; - - if ((n < MAXSIGQ) && (sigterm_info[n].si_signo)) - e->data = sigterm_info[n]; - - ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, - NULL); - } - sig_count--; - } - sigterm_count = 0; - -#ifdef SIGPWR - if (sigpwr_count > MAXSIGQ) - WRN("%i SIGPWR in queue. max queue size %i. losing " - "siginfo for extra signals.", sigpwr_count, MAXSIGQ); - for (n = 0; n < sigpwr_count; n++) { - Ecore_Event_Signal_Power *e; - - e = _ecore_event_signal_power_new(); - if (e) { - if ((n < MAXSIGQ) && (sigpwr_info[n].si_signo)) - e->data = sigpwr_info[n]; - - ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e, NULL, - NULL); - } - sig_count--; - } - sigpwr_count = 0; -#endif - -#ifdef SIGRTMIN - for (i = 0; i < num; i++) { - if (sigrt_count[i] > MAXSIGQ) - WRN("%i SIGRT%i in queue. max queue size %i. losing " "siginfo for extra signals.", i + 1, sigrt_count[i], MAXSIGQ); - for (n = 0; n < sigrt_count[i]; n++) { - Ecore_Event_Signal_Realtime *e; - - if ((e = _ecore_event_signal_realtime_new())) { - e->num = i; - - if ((n < MAXSIGQ) - && (sigrt_info[n][i].si_signo)) - e->data = sigrt_info[n][i]; - - ecore_event_add - (ECORE_EVENT_SIGNAL_REALTIME, e, NULL, - NULL); - } - sig_count--; - } - sigrt_count[i] = 0; - } -#endif - sigprocmask(SIG_SETMASK, &oldset, NULL); -} - -static void _ecore_signal_callback_set(int sig, Signal_Handler func) -{ - struct sigaction sa; - - sa.sa_sigaction = func; - sa.sa_flags = SA_RESTART | SA_SIGINFO; - sigemptyset(&sa.sa_mask); - sigaction(sig, &sa, NULL); -} - -static void -_ecore_signal_callback_ignore(int sig __UNUSED__, - siginfo_t * si __UNUSED__, - void *foo __UNUSED__) -{ -} - -static void -_ecore_signal_callback_sigchld(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigchld_info[n] = *si; - else - sigchld_info[n].si_signo = 0; - } - - sigchld_count++; - sig_count++; -} - -static void -_ecore_signal_callback_sigusr1(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigusr1_info[n] = *si; - else - sigusr1_info[n].si_signo = 0; - } - sigusr1_count++; - sig_count++; -} - -static void -_ecore_signal_callback_sigusr2(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigusr2_info[n] = *si; - else - sigusr2_info[n].si_signo = 0; - } - sigusr2_count++; - sig_count++; -} - -static void -_ecore_signal_callback_sighup(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sighup_info[n] = *si; - else - sighup_info[n].si_signo = 0; - } - sighup_count++; - sig_count++; -} - -static void -_ecore_signal_callback_sigquit(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigquit_info[n] = *si; - else - sigquit_info[n].si_signo = 0; - } - sigquit_count++; - sig_count++; -} - -static void -_ecore_signal_callback_sigint(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigint_info[n] = *si; - else - sigint_info[n].si_signo = 0; - } - sigint_count++; - sig_count++; -} - -static void -_ecore_signal_callback_sigterm(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigterm_info[n] = *si; - else - sigterm_info[n].si_signo = 0; - } - sigterm_count++; - sig_count++; -} - -#ifdef SIGPWR -static void -_ecore_signal_callback_sigpwr(int sig __UNUSED__, siginfo_t * si, - void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigpwr_info[n] = *si; - else - sigpwr_info[n].si_signo = 0; - } - sigpwr_count++; - sig_count++; -} -#endif - -#ifdef SIGRTMIN -static void -_ecore_signal_callback_sigrt(int sig, siginfo_t * si, void *foo __UNUSED__) -{ - volatile sig_atomic_t n; - n = sigchld_count; - if (n < MAXSIGQ) { - if (si) - sigrt_info[n][sig - SIGRTMIN] = *si; - else - sigrt_info[n][sig - SIGRTMIN].si_signo = 0; - } - sigrt_count[sig - SIGRTMIN]++; - sig_count++; -} -#endif - -static Eina_Bool _ecore_signal_exe_exit_delay(void *data) -{ - Ecore_Exe_Event_Del *e; - - e = data; - if (e) { - _ecore_exe_doomsday_clock_set(e->exe, NULL); - _ecore_event_add(ECORE_EXE_EVENT_DEL, e, - _ecore_exe_event_del_free, NULL); - } - return ECORE_CALLBACK_CANCEL; -} diff --git a/tests/suite/ecore/src/lib/ecore_thread.c b/tests/suite/ecore/src/lib/ecore_thread.c deleted file mode 100644 index 27a924f7e5..0000000000 --- a/tests/suite/ecore/src/lib/ecore_thread.c +++ /dev/null @@ -1,1261 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#ifdef EFL_HAVE_PTHREAD -#include <pthread.h> -#ifdef __linux__ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif -#include <sched.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <unistd.h> -#include <sys/syscall.h> -#include <errno.h> -#endif -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -typedef struct _Ecore_Pthread_Worker Ecore_Pthread_Worker; -typedef struct _Ecore_Pthread Ecore_Pthread; -typedef struct _Ecore_Thread_Data Ecore_Thread_Data; - -struct _Ecore_Thread_Data { - void *data; - Eina_Free_Cb cb; -}; - -struct _Ecore_Pthread_Worker { - union { - struct { - Ecore_Cb func_blocking; - } short_run; - struct { - Ecore_Thread_Heavy_Cb func_heavy; - Ecore_Thread_Notify_Cb func_notify; - Ecore_Pipe *notify; - } feedback_run; - } u; - - Ecore_Cb func_cancel; - Ecore_Cb func_end; -#ifdef EFL_HAVE_PTHREAD - pthread_t self; - Eina_Hash *hash; - pthread_cond_t cond; - pthread_mutex_t mutex; -#endif - - const void *data; - - Eina_Bool cancel:1; - Eina_Bool feedback_run:1; -}; - -#ifdef EFL_HAVE_PTHREAD -typedef struct _Ecore_Pthread_Data Ecore_Pthread_Data; - -struct _Ecore_Pthread_Data { - Ecore_Pipe *p; - void *data; - pthread_t thread; -}; -#endif - -static int _ecore_thread_count_max = 0; -static int ECORE_THREAD_PIPE_DEL = 0; - -#ifdef EFL_HAVE_PTHREAD -static int _ecore_thread_count = 0; - -static Eina_List *_ecore_active_job_threads = NULL; -static Eina_List *_ecore_pending_job_threads = NULL; -static Eina_List *_ecore_pending_job_threads_feedback = NULL; -static Ecore_Event_Handler *del_handler = NULL; -static pthread_mutex_t _ecore_pending_job_threads_mutex = - PTHREAD_MUTEX_INITIALIZER; - -static Eina_Hash *_ecore_thread_global_hash = NULL; -static pthread_rwlock_t _ecore_thread_global_hash_lock = - PTHREAD_RWLOCK_INITIALIZER; -static pthread_mutex_t _ecore_thread_global_hash_mutex = - PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t _ecore_thread_global_hash_cond = - PTHREAD_COND_INITIALIZER; -static pthread_t main_loop_thread; -static Eina_Bool have_main_loop_thread = 0; -static void _ecore_thread_data_free(void *data) -{ - Ecore_Thread_Data *d = data; - - if (d->cb) - d->cb(d->data); - free(d); -} - -static void _ecore_thread_pipe_free(void *data __UNUSED__, void *event) -{ - Ecore_Pipe *p = event; - - ecore_pipe_del(p); -} - -static Eina_Bool -_ecore_thread_pipe_del(void *data __UNUSED__, int type __UNUSED__, - void *event __UNUSED__) -{ - /* This is a hack to delay pipe destruction until we are out of its internal loop. */ - return ECORE_CALLBACK_CANCEL; -} - -static void _ecore_thread_end(Ecore_Pthread_Data * pth) -{ - Ecore_Pipe *p; - - if (pthread_join(pth->thread, (void **) &p) != 0) - return; - - _ecore_active_job_threads = - eina_list_remove(_ecore_active_job_threads, pth); - - ecore_event_add(ECORE_THREAD_PIPE_DEL, pth->p, - _ecore_thread_pipe_free, NULL); - free(pth); -} - -static void -_ecore_thread_handler(void *data __UNUSED__, void *buffer, - unsigned int nbyte) -{ - Ecore_Pthread_Worker *work; - - if (nbyte != sizeof(Ecore_Pthread_Worker *)) - return; - - work = *(Ecore_Pthread_Worker **) buffer; - - if (work->cancel) { - if (work->func_cancel) - work->func_cancel((void *) work->data); - } else { - if (work->func_end) - work->func_end((void *) work->data); - } - - if (work->feedback_run) - ecore_pipe_del(work->u.feedback_run.notify); - pthread_cond_destroy(&work->cond); - pthread_mutex_destroy(&work->mutex); - if (work->hash) - eina_hash_free(work->hash); - free(work); -} - -static void -_ecore_notify_handler(void *data, void *buffer, unsigned int nbyte) -{ - Ecore_Pthread_Worker *work = data; - void *user_data; - - if (nbyte != sizeof(Ecore_Pthread_Worker *)) - return; - - user_data = *(void **) buffer; - - if (work->u.feedback_run.func_notify) - work->u.feedback_run.func_notify((Ecore_Thread *) work, - user_data, - (void *) work->data); -} - -static void _ecore_short_job(Ecore_Pipe * end_pipe) -{ - Ecore_Pthread_Worker *work; - - while (_ecore_pending_job_threads) { - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - - if (!_ecore_pending_job_threads) { - pthread_mutex_unlock - (&_ecore_pending_job_threads_mutex); - break; - } - - work = eina_list_data_get(_ecore_pending_job_threads); - _ecore_pending_job_threads = - eina_list_remove_list(_ecore_pending_job_threads, - _ecore_pending_job_threads); - - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - if (!work->cancel) - work->u.short_run.func_blocking((void *) work-> - data); - - ecore_pipe_write(end_pipe, &work, - sizeof(Ecore_Pthread_Worker *)); - } -} - -static void _ecore_feedback_job(Ecore_Pipe * end_pipe, pthread_t thread) -{ - Ecore_Pthread_Worker *work; - - while (_ecore_pending_job_threads_feedback) { - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - - if (!_ecore_pending_job_threads_feedback) { - pthread_mutex_unlock - (&_ecore_pending_job_threads_mutex); - break; - } - - work = - eina_list_data_get - (_ecore_pending_job_threads_feedback); - _ecore_pending_job_threads_feedback = - eina_list_remove_list - (_ecore_pending_job_threads_feedback, - _ecore_pending_job_threads_feedback); - - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - work->self = thread; - if (!work->cancel) - work->u.feedback_run. - func_heavy((Ecore_Thread *) work, - (void *) work->data); - - ecore_pipe_write(end_pipe, &work, - sizeof(Ecore_Pthread_Worker *)); - } -} - -static void *_ecore_direct_worker(Ecore_Pthread_Worker * work) -{ - Ecore_Pthread_Data *pth; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - eina_sched_prio_drop(); - - pth = malloc(sizeof(Ecore_Pthread_Data)); - if (!pth) - return NULL; - - pth->p = ecore_pipe_add(_ecore_thread_handler, NULL); - if (!pth->p) { - free(pth); - return NULL; - } - pth->thread = pthread_self(); - - work->self = pth->thread; - work->u.feedback_run.func_heavy((Ecore_Thread *) work, - (void *) work->data); - - ecore_pipe_write(pth->p, &work, sizeof(Ecore_Pthread_Worker *)); - - work = malloc(sizeof(Ecore_Pthread_Worker)); - if (!work) { - ecore_pipe_del(pth->p); - free(pth); - return NULL; - } - - work->data = pth; - work->u.short_run.func_blocking = NULL; - work->func_end = (void *) _ecore_thread_end; - work->func_cancel = NULL; - work->cancel = EINA_FALSE; - work->feedback_run = EINA_FALSE; - work->hash = NULL; - pthread_cond_init(&work->cond, NULL); - pthread_mutex_init(&work->mutex, NULL); - - ecore_pipe_write(pth->p, &work, sizeof(Ecore_Pthread_Worker *)); - - return pth->p; -} - -static void *_ecore_thread_worker(Ecore_Pthread_Data * pth) -{ - Ecore_Pthread_Worker *work; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - eina_sched_prio_drop(); - - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - _ecore_thread_count++; - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - on_error: - if (_ecore_pending_job_threads) - _ecore_short_job(pth->p); - if (_ecore_pending_job_threads_feedback) - _ecore_feedback_job(pth->p, pth->thread); - - /* FIXME: Check if there is feedback running task todo, and switch to feedback run handler. */ - - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - if (_ecore_pending_job_threads) { - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - goto on_error; - } - if (_ecore_pending_job_threads_feedback) { - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - goto on_error; - } - - _ecore_thread_count--; - - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - work = malloc(sizeof(Ecore_Pthread_Worker)); - if (!work) - return NULL; - - work->data = pth; - work->u.short_run.func_blocking = NULL; - work->func_end = (void *) _ecore_thread_end; - work->func_cancel = NULL; - work->cancel = EINA_FALSE; - work->feedback_run = EINA_FALSE; - work->hash = NULL; - pthread_cond_init(&work->cond, NULL); - pthread_mutex_init(&work->mutex, NULL); - - ecore_pipe_write(pth->p, &work, sizeof(Ecore_Pthread_Worker *)); - - return pth->p; -} - -#endif - -void _ecore_thread_init(void) -{ - _ecore_thread_count_max = eina_cpu_count(); - if (_ecore_thread_count_max <= 0) - _ecore_thread_count_max = 1; - - ECORE_THREAD_PIPE_DEL = ecore_event_type_new(); -#ifdef EFL_HAVE_PTHREAD - del_handler = - ecore_event_handler_add(ECORE_THREAD_PIPE_DEL, - _ecore_thread_pipe_del, NULL); - main_loop_thread = pthread_self(); - have_main_loop_thread = 1; -#endif -} - -void _ecore_thread_shutdown(void) -{ - /* FIXME: If function are still running in the background, should we kill them ? */ -#ifdef EFL_HAVE_PTHREAD - Ecore_Pthread_Worker *work; - Ecore_Pthread_Data *pth; - - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - - EINA_LIST_FREE(_ecore_pending_job_threads, work) { - if (work->func_cancel) - work->func_cancel((void *) work->data); - free(work); - } - - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - EINA_LIST_FREE(_ecore_active_job_threads, pth) { - Ecore_Pipe *p; - - pthread_cancel(pth->thread); - pthread_join(pth->thread, (void **) &p); - - ecore_pipe_del(pth->p); - } - if (_ecore_thread_global_hash) - eina_hash_free(_ecore_thread_global_hash); - ecore_event_handler_del(del_handler); - have_main_loop_thread = 0; - del_handler = NULL; -#endif -} - -/** - * @addtogroup Ecore_Thread Ecore Thread Functions - * These functions allow for ecore-managed threads which integrate with ecore's main loop. - * @{ - */ - -/** - * @brief Run some blocking code in a parallel thread to avoid locking the main loop. - * @param func_blocking The function that should run in another thread. - * @param func_end The function that will be called in the main loop if the thread terminate correctly. - * @param func_cancel The function that will be called in the main loop if the thread is cancelled. - * @param data User context data to pass to all callback. - * @return A reference to the newly created thread instance, or NULL if it failed. - * - * ecore_thread_run provide a facility for easily managing blocking task in a - * parallel thread. You should provide three function. The first one, func_blocking, - * that will do the blocking work in another thread (so you should not use the - * EFL in it except Eina if you are careful). The second one, func_end, - * that will be called in Ecore main loop when func_blocking is done. So you - * can use all the EFL inside this function. The last one, func_cancel, will - * be called in the main loop if the thread is cancelled or could not run at all. - * - * Be aware, that you can't make assumption on the result order of func_end - * after many call to ecore_thread_run, as we start as much thread as the - * host CPU can handle. - */ -EAPI Ecore_Thread *ecore_thread_run(Ecore_Cb func_blocking, - Ecore_Cb func_end, - Ecore_Cb func_cancel, const void *data) -{ -#ifdef EFL_HAVE_PTHREAD - Ecore_Pthread_Worker *work; - Ecore_Pthread_Data *pth = NULL; - - if (!func_blocking) - return NULL; - - work = malloc(sizeof(Ecore_Pthread_Worker)); - if (!work) { - func_cancel((void *) data); - return NULL; - } - - work->u.short_run.func_blocking = func_blocking; - work->hash = NULL; - pthread_cond_init(&work->cond, NULL); - pthread_mutex_init(&work->mutex, NULL); - work->func_end = func_end; - work->func_cancel = func_cancel; - work->cancel = EINA_FALSE; - work->feedback_run = EINA_FALSE; - work->data = data; - - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - _ecore_pending_job_threads = - eina_list_append(_ecore_pending_job_threads, work); - - if (_ecore_thread_count == _ecore_thread_count_max) { - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - return (Ecore_Thread *) work; - } - - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - /* One more thread could be created. */ - pth = malloc(sizeof(Ecore_Pthread_Data)); - if (!pth) - goto on_error; - - pth->p = ecore_pipe_add(_ecore_thread_handler, NULL); - if (!pth->p) - goto on_error; - - if (pthread_create - (&pth->thread, NULL, (void *) _ecore_thread_worker, pth) == 0) - return (Ecore_Thread *) work; - - on_error: - if (pth) { - if (pth->p) - ecore_pipe_del(pth->p); - free(pth); - } - - if (_ecore_thread_count == 0) { - if (work->func_cancel) - work->func_cancel((void *) work->data); - free(work); - work = NULL; - } - return (Ecore_Thread *) work; -#else - /* - If no thread and as we don't want to break app that rely on this - facility, we will lock the interface until we are done. - */ - func_blocking((void *) data); - func_end((void *) data); - - return NULL; -#endif -} - -/** - * @brief Cancel a running thread. - * @param thread The thread to cancel. - * @return Will return EINA_TRUE if the thread has been cancelled, - * EINA_FALSE if it is pending. - * - * ecore_thread_cancel give the possibility to cancel a task still running. It - * will return EINA_FALSE, if the destruction is delayed or EINA_TRUE if it is - * cancelled after this call. - * - * You should use this function only in the main loop. - * - * func_end, func_cancel will destroy the handler, so don't use it after. - * And if ecore_thread_cancel return EINA_TRUE, you should not use Ecore_Thread also. - */ -EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread * thread) -{ -#ifdef EFL_HAVE_PTHREAD - Ecore_Pthread_Worker *work = (Ecore_Pthread_Worker *) thread; - Eina_List *l; - - if (!work) - return EINA_TRUE; - - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - - if ((have_main_loop_thread) && - (pthread_equal(main_loop_thread, pthread_self()))) { - EINA_LIST_FOREACH(_ecore_pending_job_threads, l, work) { - if ((void *) work == (void *) thread) { - _ecore_pending_job_threads = - eina_list_remove_list - (_ecore_pending_job_threads, l); - - pthread_mutex_unlock - (&_ecore_pending_job_threads_mutex); - - if (work->func_cancel) - work->func_cancel((void *) work-> - data); - free(work); - - return EINA_TRUE; - } - } - } - - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - /* Delay the destruction */ - ((Ecore_Pthread_Worker *) thread)->cancel = EINA_TRUE; - return EINA_FALSE; -#else - return EINA_TRUE; -#endif -} - -/** - * @brief Tell if a thread was canceled or not. - * @param thread The thread to test. - * @return EINA_TRUE if the thread is cancelled, - * EINA_FALSE if it is not. - * - * You can use this function in main loop and in the thread. - */ -EAPI Eina_Bool ecore_thread_check(Ecore_Thread * thread) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread; - - if (!worker) - return EINA_TRUE; - return worker->cancel; -} - -/** - * @brief Run some heavy code in a parallel thread to avoid locking the main loop. - * @param func_heavy The function that should run in another thread. - * @param func_notify The function that will receive the data send by func_heavy in the main loop. - * @param func_end The function that will be called in the main loop if the thread terminate correctly. - * @param func_cancel The function that will be called in the main loop if the thread is cancelled. - * @param data User context data to pass to all callback. - * @param try_no_queue If you wan't to run outside of the thread pool. - * @return A reference to the newly created thread instance, or NULL if it failed. - * - * ecore_thread_feedback_run provide a facility for easily managing heavy task in a - * parallel thread. You should provide four functions. The first one, func_heavy, - * that will do the heavy work in another thread (so you should not use the - * EFL in it except Eina and Eet if you are careful). The second one, func_notify, - * will receive the data send from the thread function (func_heavy) by ecore_thread_notify - * in the main loop (and so, can use all the EFL). Tje third, func_end, - * that will be called in Ecore main loop when func_heavy is done. So you - * can use all the EFL inside this function. The last one, func_cancel, will - * be called in the main loop also, if the thread is cancelled or could not run at all. - * - * Be aware, that you can't make assumption on the result order of func_end - * after many call to ecore_feedback_run, as we start as much thread as the - * host CPU can handle. - * - * If you set try_no_queue, it will try to run outside of the thread pool, this can bring - * the CPU down, so be careful with that. Of course if it can't start a new thread, it will - * try to use one from the pool. - */ -EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Heavy_Cb - func_heavy, - Ecore_Thread_Notify_Cb - func_notify, - Ecore_Cb func_end, - Ecore_Cb func_cancel, - const void *data, - Eina_Bool try_no_queue) -{ - -#ifdef EFL_HAVE_PTHREAD - Ecore_Pthread_Worker *worker; - Ecore_Pthread_Data *pth = NULL; - - if (!func_heavy) - return NULL; - - worker = malloc(sizeof(Ecore_Pthread_Worker)); - if (!worker) - goto on_error; - - worker->u.feedback_run.func_heavy = func_heavy; - worker->u.feedback_run.func_notify = func_notify; - worker->hash = NULL; - pthread_cond_init(&worker->cond, NULL); - pthread_mutex_init(&worker->mutex, NULL); - worker->func_cancel = func_cancel; - worker->func_end = func_end; - worker->data = data; - worker->cancel = EINA_FALSE; - worker->feedback_run = EINA_TRUE; - - worker->u.feedback_run.notify = - ecore_pipe_add(_ecore_notify_handler, worker); - - if (!try_no_queue) { - pthread_t t; - - if (pthread_create - (&t, NULL, (void *) _ecore_direct_worker, worker) == 0) - return (Ecore_Thread *) worker; - } - - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - _ecore_pending_job_threads_feedback = - eina_list_append(_ecore_pending_job_threads_feedback, worker); - - if (_ecore_thread_count == _ecore_thread_count_max) { - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - return (Ecore_Thread *) worker; - } - - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - - /* One more thread could be created. */ - pth = malloc(sizeof(Ecore_Pthread_Data)); - if (!pth) - goto on_error; - - pth->p = ecore_pipe_add(_ecore_thread_handler, NULL); - if (!pth->p) - goto on_error; - - if (pthread_create - (&pth->thread, NULL, (void *) _ecore_thread_worker, pth) == 0) - return (Ecore_Thread *) worker; - - on_error: - if (pth) { - if (pth->p) - ecore_pipe_del(pth->p); - free(pth); - } - - if (_ecore_thread_count == 0) { - if (func_cancel) - func_cancel((void *) data); - - if (worker) { - ecore_pipe_del(worker->u.feedback_run.notify); - free(worker); - worker = NULL; - } - } - - return (Ecore_Thread *) worker; -#else - Ecore_Pthread_Worker worker; - - (void) try_no_queue; - - /* - If no thread and as we don't want to break app that rely on this - facility, we will lock the interface until we are done. - */ - worker.u.feedback_run.func_heavy = func_heavy; - worker.u.feedback_run.func_notify = func_notify; - worker.u.feedback_run.notify = NULL; - worker.func_cancel = func_cancel; - worker.func_end = func_end; - worker.data = data; - worker.cancel = EINA_FALSE; - worker.feedback_run = EINA_TRUE; - - func_heavy((Ecore_Thread *) & worker, (void *) data); - - if (worker.cancel) - func_cancel((void *) data); - else - func_end((void *) data); - - return NULL; -#endif -} - -/** - * @brief Send data to main loop from worker thread. - * @param thread The current Ecore_Thread context to send data from - * @param data Data to be transmitted to the main loop - * @return EINA_TRUE if data was successfully send to main loop, - * EINA_FALSE if anything goes wrong. - * - * After a succesfull call, the data should be considered owned - * by the main loop. - * - * You should use this function only in the func_heavy call. - */ -EAPI Eina_Bool -ecore_thread_feedback(Ecore_Thread * thread, const void *data) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread; - - if (!worker) - return EINA_FALSE; - if (!worker->feedback_run) - return EINA_FALSE; - -#ifdef EFL_HAVE_PTHREAD - if (!pthread_equal(worker->self, pthread_self())) - return EINA_FALSE; - - ecore_pipe_write(worker->u.feedback_run.notify, &data, - sizeof(void *)); - - return EINA_TRUE; -#else - worker->u.feedback_run.func_notify(thread, (void *) data, - (void *) worker->data); - - return EINA_TRUE; -#endif -} - -/** - * @brief Get number of active thread jobs - * @return Number of active threads running jobs - * This returns the number of threads currently running jobs through the - * ecore_thread api. - */ -EAPI int ecore_thread_active_get(void) -{ -#ifdef EFL_HAVE_PTHREAD - return _ecore_thread_count; -#else - return 0; -#endif -} - -/** - * @brief Get number of pending (short) thread jobs - * @return Number of pending threads running "short" jobs - * This returns the number of threads currently running jobs through the - * ecore_thread_run api call. - */ -EAPI int ecore_thread_pending_get(void) -{ - int ret; -#ifdef EFL_HAVE_PTHREAD - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - ret = eina_list_count(_ecore_pending_job_threads); - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -/** - * @brief Get number of pending feedback thread jobs - * @return Number of pending threads running "feedback" jobs - * This returns the number of threads currently running jobs through the - * ecore_thread_feedback_run api call. - */ -EAPI int ecore_thread_pending_feedback_get(void) -{ - int ret; -#ifdef EFL_HAVE_PTHREAD - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - ret = eina_list_count(_ecore_pending_job_threads_feedback); - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -/** - * @brief Get number of pending thread jobs - * @return Number of pending threads running jobs - * This returns the number of threads currently running jobs through the - * ecore_thread_run and ecore_thread_feedback_run api calls combined. - */ -EAPI int ecore_thread_pending_total_get(void) -{ - int ret; -#ifdef EFL_HAVE_PTHREAD - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - ret = - eina_list_count(_ecore_pending_job_threads) + - eina_list_count(_ecore_pending_job_threads_feedback); - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -/** - * @brief Get the max number of threads that can run simultaneously - * @return Max number of threads ecore will run - * This returns the total number of threads that ecore will attempt to run - * simultaneously. - */ -EAPI int ecore_thread_max_get(void) -{ - return _ecore_thread_count_max; -} - -/** - * @brief Set the max number of threads that can run simultaneously - * @param num The new maximum - * This sets the maximum number of threads that ecore will try to run - * simultaneously. This number cannot be < 1 or >= 2x the number of active cpus. - */ -EAPI void ecore_thread_max_set(int num) -{ - if (num < 1) - return; - /* avoid doing something hilarious by blocking dumb users */ - if (num >= (2 * eina_cpu_count())) - return; - - _ecore_thread_count_max = num; -} - -/** - * @brief Reset the max number of threads that can run simultaneously - * This resets the maximum number of threads that ecore will try to run - * simultaneously to the number of active cpus. - */ -EAPI void ecore_thread_max_reset(void) -{ - _ecore_thread_count_max = eina_cpu_count(); -} - -/** - * @brief Get the number of threads which are available to be used - * @return The number of available threads - * This returns the number of threads slots that ecore has currently available. - * Assuming that you haven't changed the max number of threads with @ref ecore_thread_max_set - * this should be equal to (num_cpus - (active_running + active_feedback_running)) - */ -EAPI int ecore_thread_available_get(void) -{ - int ret; -#ifdef EFL_HAVE_PTHREAD - pthread_mutex_lock(&_ecore_pending_job_threads_mutex); - ret = _ecore_thread_count_max - _ecore_thread_count; - pthread_mutex_unlock(&_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -/** - * @brief Add data to the thread for subsequent use - * @param thread The thread context to add to - * @param key The name string to add the data with - * @param value The data to add - * @param cb The callback to free the data with - * @param direct If true, this will not copy the key string (like eina_hash_direct_add) - * @return EINA_TRUE on success, EINA_FALSE on failure - * This adds data to the thread context, allowing the thread - * to retrieve and use it without complicated mutexing. This function can only be called by a - * *_run thread INSIDE the thread and will return EINA_FALSE in any case but success. - * All data added to the thread will be freed with its associated callback (if present) - * upon thread termination. If no callback is specified, it is expected that the user will free the - * data, but this is most likely not what you want. - */ -EAPI Eina_Bool -ecore_thread_local_data_add(Ecore_Thread * thread, const char *key, - void *value, Eina_Free_Cb cb, Eina_Bool direct) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread; - Ecore_Thread_Data *d; - Eina_Bool ret; - - if ((!thread) || (!key) || (!value)) - return EINA_FALSE; -#ifdef EFL_HAVE_PTHREAD - if (!pthread_equal(worker->self, pthread_self())) - return EINA_FALSE; - - if (!worker->hash) - worker->hash = - eina_hash_string_small_new(_ecore_thread_data_free); - - if (!worker->hash) - return EINA_FALSE; - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return EINA_FALSE; - - d->data = value; - d->cb = cb; - - if (direct) - ret = eina_hash_direct_add(worker->hash, key, d); - else - ret = eina_hash_add(worker->hash, key, d); - pthread_cond_broadcast(&worker->cond); - return ret; -#else - return EINA_TRUE; -#endif -} - -/** - * @brief Modify data in the thread, or add if not found - * @param thread The thread context - * @param key The name string to add the data with - * @param value The data to add - * @param cb The callback to free the data with - * @return The old data associated with @p key on success if modified, NULL if added - * This adds/modifies data in the thread context, adding only if modify fails. - * This function can only be called by a *_run thread INSIDE the thread. - * All data added to the thread pool will be freed with its associated callback (if present) - * upon thread termination. If no callback is specified, it is expected that the user will free the - * data, but this is most likely not what you want. - */ -EAPI void *ecore_thread_local_data_set(Ecore_Thread * thread, - const char *key, void *value, - Eina_Free_Cb cb) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread; - Ecore_Thread_Data *d, *r; - void *ret; - if ((!thread) || (!key) || (!value)) - return NULL; -#ifdef EFL_HAVE_PTHREAD - if (!pthread_equal(worker->self, pthread_self())) - return NULL; - - if (!worker->hash) - worker->hash = - eina_hash_string_small_new(_ecore_thread_data_free); - - if (!worker->hash) - return NULL; - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return NULL; - - d->data = value; - d->cb = cb; - - r = eina_hash_set(worker->hash, key, d); - pthread_cond_broadcast(&worker->cond); - ret = r->data; - free(r); - return ret; -#else - return NULL; -#endif -} - -/** - * @brief Find data in the thread's data - * @param thread The thread context - * @param key The name string the data is associated with - * @return The value, or NULL on error - * This finds data in the thread context that has been previously added with @ref ecore_thread_local_data_add - * This function can only be called by a *_run thread INSIDE the thread, and will return NULL - * in any case but success. - */ - -EAPI void *ecore_thread_local_data_find(Ecore_Thread * thread, - const char *key) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread; - Ecore_Thread_Data *d; - - if ((!thread) || (!key)) - return NULL; -#ifdef EFL_HAVE_PTHREAD - if (!pthread_equal(worker->self, pthread_self())) - return NULL; - - if (!worker->hash) - return NULL; - - d = eina_hash_find(worker->hash, key); - return d->data; -#else - return NULL; -#endif -} - -/** - * @brief Delete data from the thread's data - * @param thread The thread context - * @param key The name string the data is associated with - * @return EINA_TRUE on success, EINA_FALSE on failure - * This deletes the data pointer from the thread context which was previously added with @ref ecore_thread_local_data_add - * This function can only be called by a *_run thread INSIDE the thread, and will return EINA_FALSE - * in any case but success. Note that this WILL free the data if a callback was specified. - */ -EAPI Eina_Bool -ecore_thread_local_data_del(Ecore_Thread * thread, const char *key) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread; - Ecore_Thread_Data *d; - if ((!thread) || (!key)) - return EINA_FALSE; -#ifdef EFL_HAVE_PTHREAD - if (!pthread_equal(worker->self, pthread_self())) - return EINA_FALSE; - - if (!worker->hash) - return EINA_FALSE; - if ((d = eina_hash_find(worker->hash, key))) - _ecore_thread_data_free(d); - return eina_hash_del_by_key(worker->hash, key); -#else - return EINA_TRUE; -#endif -} - -/** - * @brief Add data to the global data - * @param key The name string to add the data with - * @param value The data to add - * @param cb The optional callback to free the data with once ecore is shut down - * @param direct If true, this will not copy the key string (like eina_hash_direct_add) - * @return EINA_TRUE on success, EINA_FALSE on failure - * This adds data to the global thread data, and will return EINA_FALSE in any case but success. - * All data added to global can be manually freed, or a callback can be provided with @p cb which will - * be called upon ecore_thread shutting down. Note that if you have manually freed data that a callback - * was specified for, you will most likely encounter a segv later on. - */ -EAPI Eina_Bool -ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, - Eina_Bool direct) -{ - Eina_Bool ret; - Ecore_Thread_Data *d; - - if ((!key) || (!value)) - return EINA_FALSE; -#ifdef EFL_HAVE_PTHREAD - pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock); - if (!_ecore_thread_global_hash) - _ecore_thread_global_hash = - eina_hash_string_small_new(_ecore_thread_data_free); - pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return EINA_FALSE; - - d->data = value; - d->cb = cb; - - if (!_ecore_thread_global_hash) - return EINA_FALSE; - pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock); - if (direct) - ret = - eina_hash_direct_add(_ecore_thread_global_hash, key, - d); - else - ret = eina_hash_add(_ecore_thread_global_hash, key, d); - pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); - pthread_cond_broadcast(&_ecore_thread_global_hash_cond); - return ret; -#else - return EINA_TRUE; -#endif -} - -/** - * @brief Add data to the global data - * @param key The name string to add the data with - * @param value The data to add - * @param cb The optional callback to free the data with once ecore is shut down - * @return An Ecore_Thread_Data on success, NULL on failure - * This adds data to the global thread data and returns NULL, or replaces the previous data - * associated with @p key and returning the previous data if it existed. To see if an error occurred, - * one must use eina_error_get. - * All data added to global can be manually freed, or a callback can be provided with @p cb which will - * be called upon ecore_thread shutting down. Note that if you have manually freed data that a callback - * was specified for, you will most likely encounter a segv later on. - */ -EAPI void *ecore_thread_global_data_set(const char *key, void *value, - Eina_Free_Cb cb) -{ - Ecore_Thread_Data *d, *r; - void *ret; - - if ((!key) || (!value)) - return NULL; -#ifdef EFL_HAVE_PTHREAD - pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock); - if (!_ecore_thread_global_hash) - _ecore_thread_global_hash = - eina_hash_string_small_new(_ecore_thread_data_free); - pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); - - if (!_ecore_thread_global_hash) - return NULL; - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return NULL; - - d->data = value; - d->cb = cb; - - pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock); - r = eina_hash_set(_ecore_thread_global_hash, key, d); - pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); - pthread_cond_broadcast(&_ecore_thread_global_hash_cond); - - ret = r->data; - free(r); - return ret; -#else - return NULL; -#endif -} - -/** - * @brief Find data in the global data - * @param key The name string the data is associated with - * @return The value, or NULL on error - * This finds data in the global data that has been previously added with @ref ecore_thread_global_data_add - * This function will return NULL in any case but success. - * All data added to global can be manually freed, or a callback can be provided with @p cb which will - * be called upon ecore_thread shutting down. Note that if you have manually freed data that a callback - * was specified for, you will most likely encounter a segv later on. - * @note Keep in mind that the data returned can be used by multiple threads at a time, so you will most likely want to mutex - * if you will be doing anything with it. - */ - -EAPI void *ecore_thread_global_data_find(const char *key) -{ - Ecore_Thread_Data *ret; - if (!key) - return NULL; -#ifdef EFL_HAVE_PTHREAD - if (!_ecore_thread_global_hash) - return NULL; - - pthread_rwlock_rdlock(&_ecore_thread_global_hash_lock); - ret = eina_hash_find(_ecore_thread_global_hash, key); - pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); - return ret->data; -#else - return NULL; -#endif -} - -/** - * @brief Delete data from the global data - * @param key The name string the data is associated with - * @return EINA_TRUE on success, EINA_FALSE on failure - * This deletes the data pointer from the global data which was previously added with @ref ecore_thread_global_data_add - * This function will return EINA_FALSE in any case but success. - * Note that this WILL free the data if an @c Eina_Free_Cb was specified when the data was added. - */ -EAPI Eina_Bool ecore_thread_global_data_del(const char *key) -{ - Eina_Bool ret; - Ecore_Thread_Data *d; - - if (!key) - return EINA_FALSE; -#ifdef EFL_HAVE_PTHREAD - if (!_ecore_thread_global_hash) - return EINA_FALSE; - - pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock); - if ((d = eina_hash_find(_ecore_thread_global_hash, key))) - _ecore_thread_data_free(d); - ret = eina_hash_del_by_key(_ecore_thread_global_hash, key); - pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); - return ret; -#else - return EINA_TRUE; -#endif -} - -/** - * @brief Find data in the global data and optionally wait for the data if not found - * @param key The name string the data is associated with - * @param seconds The amount of time in seconds to wait for the data. If 0, the call will be async and not wait for data. - * If < 0 the call will wait indefinitely for the data. - * @return The value, or NULL on failure - * This finds data in the global data that has been previously added with @ref ecore_thread_global_data_add - * This function will return NULL in any case but success. - * Use @p seconds to specify the amount of time to wait. Use > 0 for an actual wait time, 0 to not wait, and < 0 to wait indefinitely. - * @note Keep in mind that the data returned can be used by multiple threads at a time, so you will most likely want to mutex - * if you will be doing anything with it. - */ -EAPI void *ecore_thread_global_data_wait(const char *key, double seconds) -{ - double time = 0; - Ecore_Thread_Data *ret = NULL; - if (!key) - return NULL; -#ifdef EFL_HAVE_PTHREAD - if (!_ecore_thread_global_hash) - return NULL; - if (seconds > 0) - time = ecore_time_get() + seconds; - - while (1) { - struct timespec t = { 0, 0 }; - - t.tv_sec = (long int) time; - t.tv_nsec = - (long int) ((time - (double) t.tv_sec) * 1000000000); - pthread_rwlock_rdlock(&_ecore_thread_global_hash_lock); - ret = eina_hash_find(_ecore_thread_global_hash, key); - pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); - if ((ret) || (!seconds) - || ((seconds > 0) && (time <= ecore_time_get()))) - break; - pthread_mutex_lock(&_ecore_thread_global_hash_mutex); - pthread_cond_timedwait(&_ecore_thread_global_hash_cond, - &_ecore_thread_global_hash_mutex, - &t); - pthread_mutex_unlock(&_ecore_thread_global_hash_mutex); - } - if (ret) - return ret->data; - return NULL; -#else - return NULL; -#endif -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/ecore_time.c b/tests/suite/ecore/src/lib/ecore_time.c deleted file mode 100644 index 837aa8bbb5..0000000000 --- a/tests/suite/ecore/src/lib/ecore_time.c +++ /dev/null @@ -1,148 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -#include <time.h> - -#ifdef HAVE_CLOCK_GETTIME -static clockid_t _ecore_time_clock_id = -1; -#endif -double _ecore_time_loop_time = -1.0; - -/** - * Retrieves the current system time as a floating point value in seconds. - * - * This uses a monotonic clock and thus never goes back in time while - * machine is live (even if user changes time or timezone changes, - * however it may be reset whenever the machine is restarted). - * - * @see ecore_loop_time_get(). - * @see ecore_time_unix_get(). - * - * @return The number of seconds. Start time is not defined (it may be - * when the machine was booted, unix time, etc), all it is - * defined is that it never goes backwards (unless you got big critical - * messages when the application started). - * @ingroup Ecore_Time_Group - */ -EAPI double ecore_time_get(void) -{ -#ifdef HAVE_CLOCK_GETTIME - struct timespec t; - - if (EINA_UNLIKELY(_ecore_time_clock_id < 0)) - return ecore_time_unix_get(); - - if (EINA_UNLIKELY(clock_gettime(_ecore_time_clock_id, &t))) { - CRIT("Cannot get current time."); - /* Try to at least return the latest value retrieved */ - return _ecore_time_loop_time; - } - - return (double) t.tv_sec + (((double) t.tv_nsec) / 1000000000.0); -#else - return ecore_time_unix_get(); -#endif -} - -/** - * Retrieves the current UNIX time as a floating point value in seconds. - * - * @see ecore_time_get(). - * @see ecore_loop_time_get(). - * - * @return The number of seconds since 12.00AM 1st January 1970. - * @ingroup Ecore_Time_Group - */ -EAPI double ecore_time_unix_get(void) -{ -#ifdef HAVE_EVIL - return evil_time_get(); -#else -#ifdef HAVE_GETTIMEOFDAY - struct timeval timev; - - gettimeofday(&timev, NULL); - return (double) timev.tv_sec + - (((double) timev.tv_usec) / 1000000); -#else -#error "Your platform isn't supported yet" -#endif -#endif -} - -/** - * Retrieves the time at which the last loop stopped waiting for timeouts or - * events. - * - * This gets the time that the main loop ceased waiting for timouts and/or - * events to come in or for signals or any other interrupt source. This should - * be considered a reference point for all time based activity that should - * calculate its timepoint from the return of ecore_loop_time_get(). Use this - * UNLESS you absolutely must get the current actual timepoint - then use - * ecore_time_get(). Note that this time is meant to be used as relative to - * other times obtained on this run. If you need absolute time references, use - * ecore_time_unix_get() instead. - * - * This function can be called before any loop has ever been run, but either - * ecore_init() or ecore_time_get() must have been called once. - * - * @return The number of seconds. Start time is not defined (it may be - * when the machine was booted, unix time, etc), all it is - * defined is that it never goes backwards (unless you got big critical - * messages when the application started). - * @ingroup Ecore_Time_Group - */ -EAPI double ecore_loop_time_get(void) -{ - return _ecore_time_loop_time; -} - - -/********************** Internal methods ********************************/ - -/* TODO: Documentation says "All implementations support the system-wide - * real-time clock, which is identified by CLOCK_REALTIME. Check if the fallback - * to unix time (without specifying the resolution) might be removed - */ -void _ecore_time_init(void) -{ -#ifdef HAVE_CLOCK_GETTIME - struct timespec t; - - if (_ecore_time_clock_id != -1) - return; - - if (!clock_gettime(CLOCK_MONOTONIC, &t)) { - _ecore_time_clock_id = CLOCK_MONOTONIC; - DBG("using CLOCK_MONOTONIC."); - } else if (!clock_gettime(CLOCK_REALTIME, &t)) { - /* may go backwards */ - _ecore_time_clock_id = CLOCK_REALTIME; - WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME."); - } else { - _ecore_time_clock_id = -2; - CRIT("Cannot get a valid clock_gettime() clock id! " - "Fallback to unix time."); - } -#else -#warning "Your platform isn't supported yet" - CRIT("Platform does not support clock_gettime. " - "Fallback to unix time."); -#endif - - _ecore_time_loop_time = ecore_time_get(); -} diff --git a/tests/suite/ecore/src/lib/ecore_timer.c b/tests/suite/ecore/src/lib/ecore_timer.c deleted file mode 100644 index 5c4cecb10f..0000000000 --- a/tests/suite/ecore/src/lib/ecore_timer.c +++ /dev/null @@ -1,602 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> - -#include "Ecore.h" -#include "ecore_private.h" - - -struct _Ecore_Timer { - EINA_INLIST; - ECORE_MAGIC; - double in; - double at; - double pending; - Ecore_Task_Cb func; - void *data; - - int references; - unsigned char delete_me:1; - unsigned char just_added:1; - unsigned char frozen:1; -}; - - -static void _ecore_timer_set(Ecore_Timer * timer, double at, double in, - Ecore_Task_Cb func, void *data); - -static int timers_added = 0; -static int timers_delete_me = 0; -static Ecore_Timer *timers = NULL; -static Ecore_Timer *timer_current = NULL; -static Ecore_Timer *suspended = NULL; -static double last_check = 0.0; -static double precision = 10.0 / 1000000.0; - -/** - * @defgroup Ecore_Time_Group Ecore Time Functions - * - * Functions that deal with time. These functions include those that simply - * retrieve it in a given format, and those that create events based on it. - */ - -/** - * Retrieves the current precision used by timer infrastructure. - * - * @see ecore_timer_precision_set() - */ -EAPI double ecore_timer_precision_get(void) -{ - return precision; -} - -/** - * Sets the precision to be used by timer infrastructure. - * - * When system calculates time to expire the next timer we'll be able - * to delay the timer by the given amount so more timers will fit in - * the same dispatch, waking up the system less often and thus being - * able to save power. - * - * Be aware that kernel may delay delivery even further, these delays - * are always possible due other tasks having higher priorities or - * other scheduler policies. - * - * Example: - * We have 2 timers, one that expires in a 2.0s and another that - * expires in 2.1s, if precision is 0.1s, then the Ecore will request - * for the next expire to happen in 2.1s and not 2.0s and another one - * of 0.1 as it would before. - * - * @note Ecore is smart enough to see if there are timers in the - * precision range, if it does not, in our example if no second timer - * in (T + precision) existed, then it would use the minimum timeout. - * - * @param value allowed introduced timeout delay, in seconds. - */ -EAPI void ecore_timer_precision_set(double value) -{ - if (value < 0.0) { - ERR("Precision %f less than zero, ignored", value); - return; - } - precision = value; -} - -/** - * Creates a timer to call the given function in the given period of time. - * @param in The interval in seconds. - * @param func The given function. If @p func returns 1, the timer is - * rescheduled for the next interval @p in. - * @param data Data to pass to @p func when it is called. - * @return A timer object on success. @c NULL on failure. - * @ingroup Ecore_Time_Group - * - * This function adds a timer and returns its handle on success and NULL on - * failure. The function @p func will be called every @p in seconds. The - * function will be passed the @p data pointer as its parameter. - * - * When the timer @p func is called, it must return a value of either 1 - * (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL). - * If it returns 1, it will be called again at the next tick, or if it returns - * 0 it will be deleted automatically making any references/handles for it - * invalid. - */ -EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, - const void *data) -{ - double now; - Ecore_Timer *timer; - - if (!func) - return NULL; - if (in < 0.0) - in = 0.0; - timer = calloc(1, sizeof(Ecore_Timer)); - if (!timer) - return NULL; - ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER); - now = ecore_time_get(); - _ecore_timer_set(timer, now + in, in, func, (void *) data); - return timer; -} - -/** - * Creates a timer to call the given function in the given period of time. - * @param in The interval in seconds from current loop time. - * @param func The given function. If @p func returns 1, the timer is - * rescheduled for the next interval @p in. - * @param data Data to pass to @p func when it is called. - * @return A timer object on success. @c NULL on failure. - * @ingroup Ecore_Time_Group - * - * This is the same as ecore_timer_add(), but "now" is the time from - * ecore_loop_time_get() not ecore_time_get() as ecore_timer_add() uses. See - * ecore_timer_add() for more details. - */ -EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, - const void *data) -{ - double now; - Ecore_Timer *timer; - - if (!func) - return NULL; - if (in < 0.0) - in = 0.0; - timer = calloc(1, sizeof(Ecore_Timer)); - if (!timer) - return NULL; - ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER); - now = ecore_loop_time_get(); - _ecore_timer_set(timer, now + in, in, func, (void *) data); - return timer; -} - -/** - * Delete the specified timer from the timer list. - * @param timer The timer to delete. - * @return The data pointer set for the timer when @ref ecore_timer_add was - * called. @c NULL is returned if the function is unsuccessful. - * @ingroup Ecore_Time_Group - * - * Note: @p timer must be a valid handle. If the timer function has already - * returned 0, the handle is no longer valid (and does not need to be delete). - */ -EAPI void *ecore_timer_del(Ecore_Timer * timer) -{ - if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { - ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, - "ecore_timer_del"); - return NULL; - } - - if (timer->frozen && !timer->references) { - void *data = timer->data; - - suspended = - (Ecore_Timer *) - eina_inlist_remove(EINA_INLIST_GET(suspended), - EINA_INLIST_GET(timer)); - - if (timer->delete_me) - timers_delete_me--; - - free(timer); - return data; - } - - EINA_SAFETY_ON_TRUE_RETURN_VAL(timer->delete_me, NULL); - timer->delete_me = 1; - timers_delete_me++; - return timer->data; -} - -/** - * Change the interval the timer ticks of. If set during - * a timer call, this will affect the next interval. - * - * @param timer The timer to change. - * @param in The interval in seconds. - * @ingroup Ecore_Time_Group - */ -EAPI void ecore_timer_interval_set(Ecore_Timer * timer, double in) -{ - if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { - ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, - "ecore_timer_interval_set"); - return; - } - timer->in = in; -} - -/** - * Get the interval the timer ticks on. - * - * @param timer The timer to retrieve the interval from - * @return The interval on success. -1 on failure. - * @ingroup Ecore_Time_Group - */ -EAPI double ecore_timer_interval_get(Ecore_Timer * timer) -{ - if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { - ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, - "ecore_timer_interval_get"); - return -1.0; - } - - return timer->in; -} - -/** - * Add some delay for the next occurrence of a timer. - * This doesn't affect the interval of a timer. - * - * @param timer The timer to change. - * @param add The dalay to add to the next iteration. - * @ingroup Ecore_Time_Group - */ -EAPI void ecore_timer_delay(Ecore_Timer * timer, double add) -{ - if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { - ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, - "ecore_timer_delay"); - return; - } - - if (timer->frozen) { - timer->pending += add; - } else { - timers = - (Ecore_Timer *) - eina_inlist_remove(EINA_INLIST_GET(timers), - EINA_INLIST_GET(timer)); - _ecore_timer_set(timer, timer->at + add, timer->in, - timer->func, timer->data); - } -} - -/** - * Get the pending time regarding a timer. - * - * @param timer The timer to learn from. - * @ingroup Ecore_Time_Group - */ -EAPI double ecore_timer_pending_get(Ecore_Timer * timer) -{ - double now; - - if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { - ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, - "ecore_timer_pending_get"); - return 0; - } - - now = ecore_time_get(); - - if (timer->frozen) - return timer->pending; - return timer->at - now; -} - -/** - * - * - */ -EAPI void ecore_timer_freeze(Ecore_Timer * timer) -{ - double now; - - if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { - ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, - "ecore_timer_freeze"); - return; - } - - /* Timer already frozen */ - if (timer->frozen) - return; - - timers = - (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), - EINA_INLIST_GET(timer)); - suspended = - (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(suspended), - EINA_INLIST_GET(timer)); - - now = ecore_time_get(); - - timer->pending = timer->at - now; - timer->at = 0.0; - timer->frozen = 1; -} - -EAPI void ecore_timer_thaw(Ecore_Timer * timer) -{ - double now; - - if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { - ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, - "ecore_timer_thaw"); - return; - } - - /* Timer not frozen */ - if (!timer->frozen) - return; - - suspended = - (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), - EINA_INLIST_GET(timer)); - now = ecore_time_get(); - - _ecore_timer_set(timer, timer->pending + now, timer->in, - timer->func, timer->data); -} - -void _ecore_timer_shutdown(void) -{ - Ecore_Timer *timer; - - while ((timer = timers)) { - timers = - (Ecore_Timer *) - eina_inlist_remove(EINA_INLIST_GET(timers), - EINA_INLIST_GET(timers)); - ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE); - free(timer); - } - - while ((timer = suspended)) { - suspended = - (Ecore_Timer *) - eina_inlist_remove(EINA_INLIST_GET(suspended), - EINA_INLIST_GET(suspended)); - ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE); - free(timer); - } - - timer_current = NULL; -} - -void _ecore_timer_cleanup(void) -{ - Ecore_Timer *l; - int in_use = 0, todo = timers_delete_me, done = 0; - - if (!timers_delete_me) - return; - for (l = timers; l;) { - Ecore_Timer *timer = l; - - l = (Ecore_Timer *) EINA_INLIST_GET(l)->next; - if (timer->delete_me) { - if (timer->references) { - in_use++; - continue; - } - timers = - (Ecore_Timer *) - eina_inlist_remove(EINA_INLIST_GET(timers), - EINA_INLIST_GET(timer)); - ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE); - free(timer); - timers_delete_me--; - done++; - if (timers_delete_me == 0) - return; - } - } - for (l = suspended; l;) { - Ecore_Timer *timer = l; - - l = (Ecore_Timer *) EINA_INLIST_GET(l)->next; - if (timer->delete_me) { - if (timer->references) { - in_use++; - continue; - } - suspended = - (Ecore_Timer *) - eina_inlist_remove(EINA_INLIST_GET(suspended), - EINA_INLIST_GET(timer)); - ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE); - free(timer); - timers_delete_me--; - done++; - if (timers_delete_me == 0) - return; - } - } - - if ((!in_use) && (timers_delete_me)) { - ERR("%d timers to delete, but they were not found!" - "Stats: todo=%d, done=%d, pending=%d, in_use=%d. " - "reset counter.", - timers_delete_me, todo, done, todo - done, in_use); - timers_delete_me = 0; - } -} - -void _ecore_timer_enable_new(void) -{ - Ecore_Timer *timer; - - if (!timers_added) - return; - timers_added = 0; - EINA_INLIST_FOREACH(timers, timer) timer->just_added = 0; -} - -int _ecore_timers_exists(void) -{ - Ecore_Timer *timer = timers; - - while ((timer) && (timer->delete_me)) - timer = (Ecore_Timer *) EINA_INLIST_GET(timer)->next; - - return ! !timer; -} - -static inline Ecore_Timer *_ecore_timer_first_get(void) -{ - Ecore_Timer *timer = timers; - - while ((timer) && ((timer->delete_me) || (timer->just_added))) - timer = (Ecore_Timer *) EINA_INLIST_GET(timer)->next; - - return timer; -} - -static inline Ecore_Timer *_ecore_timer_after_get(Ecore_Timer * base) -{ - Ecore_Timer *timer = (Ecore_Timer *) EINA_INLIST_GET(base)->next; - double maxtime = base->at + precision; - - while ((timer) && ((timer->delete_me) || (timer->just_added)) - && (timer->at <= maxtime)) - timer = (Ecore_Timer *) EINA_INLIST_GET(timer)->next; - - if ((!timer) || (timer->at > maxtime)) - return NULL; - - return timer; -} - -double _ecore_timer_next_get(void) -{ - double now; - double in; - Ecore_Timer *first, *second; - - first = _ecore_timer_first_get(); - if (!first) - return -1; - - second = _ecore_timer_after_get(first); - if (second) - first = second; - - now = ecore_loop_time_get(); - in = first->at - now; - if (in < 0) - in = 0; - return in; -} - -static inline void -_ecore_timer_reschedule(Ecore_Timer * timer, double when) -{ - if ((timer->delete_me) || (timer->frozen)) - return; - - timers = - (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), - EINA_INLIST_GET(timer)); - - /* if the timer would have gone off more than 15 seconds ago, - * assume that the system hung and set the timer to go off - * timer->in from now. this handles system hangs, suspends - * and more, so ecore will only "replay" the timers while - * the system is suspended if it is suspended for less than - * 15 seconds (basically). this also handles if the process - * is stopped in a debugger or IO and other handling gets - * really slow within the main loop. - */ - if ((timer->at + timer->in) < (when - 15.0)) - _ecore_timer_set(timer, when + timer->in, timer->in, - timer->func, timer->data); - else - _ecore_timer_set(timer, timer->at + timer->in, timer->in, - timer->func, timer->data); -} - -int _ecore_timer_call(double when) -{ - if (!timers) - return 0; - if (last_check > when) { - Ecore_Timer *timer; - /* User set time backwards */ - EINA_INLIST_FOREACH(timers, timer) timer->at -= - (last_check - when); - } - last_check = when; - - if (!timer_current) { - /* regular main loop, start from head */ - timer_current = timers; - } else { - /* recursive main loop, continue from where we were */ - Ecore_Timer *timer_old = timer_current; - timer_current = - (Ecore_Timer *) EINA_INLIST_GET(timer_current)->next; - _ecore_timer_reschedule(timer_old, when); - } - - while (timer_current) { - Ecore_Timer *timer = timer_current; - - if (timer->at > when) { - timer_current = NULL; /* ended walk, next should restart. */ - return 0; - } - - if ((timer->just_added) || (timer->delete_me)) { - timer_current = - (Ecore_Timer *) - EINA_INLIST_GET(timer_current)->next; - continue; - } - - timer->references++; - if (!timer->func(timer->data)) { - if (!timer->delete_me) - ecore_timer_del(timer); - } - timer->references--; - - if (timer_current) /* may have changed in recursive main loops */ - timer_current = - (Ecore_Timer *) - EINA_INLIST_GET(timer_current)->next; - - _ecore_timer_reschedule(timer, when); - } - return 0; -} - -static void -_ecore_timer_set(Ecore_Timer * timer, double at, double in, - Ecore_Task_Cb func, void *data) -{ - Ecore_Timer *t2; - - timers_added = 1; - timer->at = at; - timer->in = in; - timer->func = func; - timer->data = data; - timer->just_added = 1; - timer->frozen = 0; - timer->pending = 0.0; - if (timers) { - EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(timers), t2) { - if (timer->at > t2->at) { - timers = - (Ecore_Timer *) - eina_inlist_append_relative - (EINA_INLIST_GET(timers), - EINA_INLIST_GET(timer), - EINA_INLIST_GET(t2)); - return; - } - } - } - timers = - (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(timers), - EINA_INLIST_GET(timer)); -} diff --git a/tests/suite/ecore/src/lib/eina_accessor.c b/tests/suite/ecore/src/lib/eina_accessor.c deleted file mode 100644 index 74e2769f3f..0000000000 --- a/tests/suite/ecore/src/lib/eina_accessor.c +++ /dev/null @@ -1,260 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> - -#include "eina_config.h" -#include "eina_private.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_accessor.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static const char EINA_MAGIC_ACCESSOR_STR[] = "Eina Accessor"; - -#define EINA_MAGIC_CHECK_ACCESSOR(d) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ACCESSOR)) { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_ACCESSOR); } \ - } while(0) - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the accessor module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the accessor module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_accessor_init(void) -{ - return eina_magic_string_set(EINA_MAGIC_ACCESSOR, - EINA_MAGIC_ACCESSOR_STR); -} - -/** - * @internal - * @brief Shut down the accessor module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the accessor module set up by - * eina_accessor_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_accessor_shutdown(void) -{ - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Accessor_Group Accessor Functions - * - * @brief These functions manage accessor on containers. - * - * These functions allow to access elements of a container in a - * generic way, without knowing which container is used (a bit like - * iterators in the C++ STL). Accessors allows random access (that is, any - * element in the container). For sequential access, see - * @ref Eina_Iterator_Group. - * - * An accessor is created from container data types, so no creation - * function is available here. An accessor is deleted with - * eina_accessor_free(). To get the data of an element at a given - * position, use eina_accessor_data_get(). To call a function on - * chosen elements of a container, use eina_accessor_over(). - * - * @{ - */ - -/** - * @brief Free an accessor. - * - * @param accessor The accessor to free. - * - * This function frees @p accessor if it is not @c NULL; - */ -EAPI void eina_accessor_free(Eina_Accessor * accessor) -{ - EINA_MAGIC_CHECK_ACCESSOR(accessor); - EINA_SAFETY_ON_NULL_RETURN(accessor); - EINA_SAFETY_ON_NULL_RETURN(accessor->free); - accessor->free(accessor); -} - -/** - * @brief Return the container of an accessor. - * - * @param accessor The accessor. - * @return The container which created the accessor. - * - * This function returns the container which created @p accessor. If - * @p accessor is @c NULL, this function returns @c NULL. - */ -EAPI void *eina_accessor_container_get(Eina_Accessor * accessor) -{ - EINA_MAGIC_CHECK_ACCESSOR(accessor); - EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(accessor->get_container, NULL); - return accessor->get_container(accessor); -} - -/** - * @brief Retrieve the data of an accessor at a given position. - * - * @param accessor The accessor. - * @param position The position of the element. - * @param data The pointer that stores the data to retrieve. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function retrieves the data of the element pointed by - * @p accessor at the porition @p position, and stores it in - * @p data. If @p accessor is @c NULL or if an error occurred, - * #EINA_FALSE is returned, otherwise EINA_TRUE is returned. - */ -EAPI Eina_Bool -eina_accessor_data_get(Eina_Accessor * accessor, - unsigned int position, void **data) -{ - EINA_MAGIC_CHECK_ACCESSOR(accessor); - EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(accessor->get_at, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); - return accessor->get_at(accessor, position, data); -} - -/** - * @brief Iterate over the container and execute a callback on chosen elements. - * - * @param accessor The accessor. - * @param cb The callback called on the chosen elements. - * @param start The position of the first element. - * @param end The position of the last element. - * @param fdata The data passed to the callback. - * - * This function iterates over the elements pointed by @p accessor, - * starting from the element at position @p start and ending to the - * element at position @p end. For Each element, the callback - * @p cb is called with the data @p fdata. If @p accessor is @c NULL - * or if @p start is greter or equal than @p end, the function returns - * immediately. - */ -EAPI void -eina_accessor_over(Eina_Accessor * accessor, - Eina_Each_Cb cb, - unsigned int start, unsigned int end, const void *fdata) -{ - const void *container; - void *data; - unsigned int i; - - EINA_MAGIC_CHECK_ACCESSOR(accessor); - EINA_SAFETY_ON_NULL_RETURN(accessor); - EINA_SAFETY_ON_NULL_RETURN(accessor->get_container); - EINA_SAFETY_ON_NULL_RETURN(accessor->get_at); - EINA_SAFETY_ON_NULL_RETURN(cb); - EINA_SAFETY_ON_FALSE_RETURN(start < end); - - if (!eina_accessor_lock(accessor)) - return; - - container = accessor->get_container(accessor); - for (i = start; - i < end && accessor->get_at(accessor, i, &data) == EINA_TRUE; - ++i) - if (cb(container, data, (void *) fdata) != EINA_TRUE) - goto on_exit; - - on_exit: - (void) eina_accessor_unlock(accessor); -} - -/** - * @brief Lock the container of the accessor. - * - * @param accessor The accessor. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * If the container of the @p accessor permit it, it will be locked. - * If @p accessor is @c NULL or if a problem occurred, #EINA_FALSE is - * returned, otherwise #EINA_TRUE is returned. If the container - * is not lockable, it will return EINA_TRUE. - */ -EAPI Eina_Bool eina_accessor_lock(Eina_Accessor * accessor) -{ - EINA_MAGIC_CHECK_ACCESSOR(accessor); - EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, EINA_FALSE); - - if (accessor->lock) - return accessor->lock(accessor); - return EINA_TRUE; -} - -/** - * @brief Unlock the container of the accessor. - * - * @param accessor The accessor. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * If the container of the @p accessor permit it and was previously - * locked, it will be unlocked. If @p accessor is @c NULL or if a - * problem occurred, #EINA_FALSE is returned, otherwise #EINA_TRUE - * is returned. If the container is not lockable, it will return - * EINA_TRUE. - */ -EAPI Eina_Bool eina_accessor_unlock(Eina_Accessor * accessor) -{ - EINA_MAGIC_CHECK_ACCESSOR(accessor); - EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, EINA_FALSE); - - if (accessor->unlock) - return accessor->unlock(accessor); - return EINA_TRUE; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_array.c b/tests/suite/ecore/src/lib/eina_array.c deleted file mode 100644 index b43e289475..0000000000 --- a/tests/suite/ecore/src/lib/eina_array.c +++ /dev/null @@ -1,702 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - - -/** - * @page tutorial_array_page Array Tutorial - * - * The Array data type is allow the storage of data like a C array. - * It is designed such that the access to its element is very fast. - * But the addition or removal can be done only at the end of the - * array. To add or remove an element at any location, the Eina - * @ref Eina_List_Group is the correct container is the correct one. - * - * @section tutorial_error_basic_usage Basic Usage - * - * An array must created with eina_array_new(). That function - * takes an integer as parameter, which is the count of pointers to - * add when increasing the array size. Once the array is not used - * anymore, it must be destroyed with eina_array_free(). - * - * To append data at the end of the array, the function - * eina_array_push() must be used. To remove the data at the end of - * the array, eina_array_pop() must be used. Once the array is filled, - * one can check its elements by iterating over it. A while loop and - * eina_array_data_get() can be used, or else one can use the - * predefined macro EINA_ARRAY_ITER_NEXT(). To free all the elements, - * a while loop can be used with eina_array_count_get(). Here is an - * example of use: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * #include <string.h> - * - * #include <eina_array.h> - * - * int main(void) - * { - * const char *strings[] = { - * "first string", - * "second string", - * "third string", - * "fourth string" - * }; - * Eina_Array *array; - * char *item; - * Eina_Array_Iterator iterator; - * unsigned int i; - * - * if (!eina_init()) - * { - * printf ("Error during the initialization of eina\n"); - * return EXIT_FAILURE; - * } - * - * array = eina_array_new(16); - * if (!array) - * goto shutdown; - * - * for (i = 0; i < 4; i++) - * { - * eina_array_push(array, strdup(strings[i])); - * } - * - * printf("array count: %d\n", eina_array_count_get(array)); - * EINA_ARRAY_ITER_NEXT(array, i, item, iterator) - * { - * printf("item #%d: %s\n", i, item); - * } - * - * while (eina_array_count_get(array)) - * { - * void *data; - * - * data = eina_array_pop(array); - * free(data); - * } - * - * eina_array_free(array); - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * - * shutdown: - * eina_shutdown(); - * - * return EXIT_FAILURE; - * } - * @endcode - * - * To be continued - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_error.h" -#include "eina_log.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_array.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - -static const char EINA_MAGIC_ARRAY_STR[] = "Eina Array"; -static const char EINA_MAGIC_ARRAY_ITERATOR_STR[] = "Eina Array Iterator"; -static const char EINA_MAGIC_ARRAY_ACCESSOR_STR[] = "Eina Array Accessor"; - -#define EINA_MAGIC_CHECK_ARRAY(d) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ARRAY)) { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_ARRAY); } \ - } while (0) - -#define EINA_MAGIC_CHECK_ARRAY_ITERATOR(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ARRAY_ITERATOR)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_ARRAY_ITERATOR); \ - return __VA_ARGS__; \ - } \ - } while (0) - -#define EINA_MAGIC_CHECK_ARRAY_ACCESSOR(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ARRAY_ACCESSOR)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_ACCESSOR); \ - return __VA_ARGS__; \ - } \ - } while (0) - - -typedef struct _Eina_Iterator_Array Eina_Iterator_Array; -struct _Eina_Iterator_Array { - Eina_Iterator iterator; - - const Eina_Array *array; - unsigned int index; - - EINA_MAGIC}; - -typedef struct _Eina_Accessor_Array Eina_Accessor_Array; -struct _Eina_Accessor_Array { - Eina_Accessor accessor; - const Eina_Array *array; - EINA_MAGIC}; - -static int _eina_array_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_array_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_array_log_dom, __VA_ARGS__) - -static void eina_array_iterator_free(Eina_Iterator_Array * - it) EINA_ARG_NONNULL(1); -static Eina_Array *eina_array_iterator_get_container(Eina_Iterator_Array * - it) -EINA_ARG_NONNULL(1); -static Eina_Bool eina_array_iterator_next(Eina_Iterator_Array * it, - void **data) EINA_ARG_NONNULL(1); - -static Eina_Bool eina_array_accessor_get_at(Eina_Accessor_Array * it, - unsigned int idx, - void **data) -EINA_ARG_NONNULL(1); -static Eina_Array *eina_array_accessor_get_container(Eina_Accessor_Array * - it) -EINA_ARG_NONNULL(1); -static void eina_array_accessor_free(Eina_Accessor_Array * - it) EINA_ARG_NONNULL(1); - -static Eina_Bool -eina_array_iterator_next(Eina_Iterator_Array * it, void **data) -{ - EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, EINA_FALSE); - - if (!(it->index < eina_array_count_get(it->array))) - return EINA_FALSE; - - if (data) - *data = eina_array_data_get(it->array, it->index); - - it->index++; - return EINA_TRUE; -} - -static Eina_Array *eina_array_iterator_get_container(Eina_Iterator_Array * - it) -{ - EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, NULL); - return (Eina_Array *) it->array; -} - -static void eina_array_iterator_free(Eina_Iterator_Array * it) -{ - EINA_MAGIC_CHECK_ARRAY_ITERATOR(it); - MAGIC_FREE(it); -} - -static Eina_Bool -eina_array_accessor_get_at(Eina_Accessor_Array * it, - unsigned int idx, void **data) -{ - EINA_MAGIC_CHECK_ARRAY_ACCESSOR(it, EINA_FALSE); - - if (!(idx < eina_array_count_get(it->array))) - return EINA_FALSE; - - if (data) - *data = eina_array_data_get(it->array, idx); - - return EINA_TRUE; -} - -static Eina_Array *eina_array_accessor_get_container(Eina_Accessor_Array * - it) -{ - EINA_MAGIC_CHECK_ARRAY_ACCESSOR(it, NULL); - return (Eina_Array *) it->array; -} - -static void eina_array_accessor_free(Eina_Accessor_Array * it) -{ - EINA_MAGIC_CHECK_ARRAY_ACCESSOR(it); - MAGIC_FREE(it); -} - -EAPI Eina_Bool eina_array_grow(Eina_Array * array) -{ - void **tmp; - unsigned int total; - - EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE); - - EINA_MAGIC_CHECK_ARRAY(array); - - total = array->total + array->step; - eina_error_set(0); - tmp = realloc(array->data, sizeof(void *) * total); - if (EINA_UNLIKELY(!tmp)) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return 0; - } - - array->total = total; - array->data = tmp; - - return 1; -} - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - -/** - * @internal - * @brief Initialize the array module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the error and magic modules or Eina. It is - * called by eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_array_init(void) -{ - _eina_array_log_dom = eina_log_domain_register("eina_array", - EINA_LOG_COLOR_DEFAULT); - if (_eina_array_log_dom < 0) { - EINA_LOG_ERR("Could not register log domain: eina_array"); - return EINA_FALSE; - } -#define EMS(n) eina_magic_string_static_set(n, n ## _STR) - EMS(EINA_MAGIC_ARRAY); - EMS(EINA_MAGIC_ARRAY_ITERATOR); - EMS(EINA_MAGIC_ARRAY_ACCESSOR); -#undef EMS - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the array module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the array module set up by - * eina_array_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_array_shutdown(void) -{ - eina_log_domain_unregister(_eina_array_log_dom); - _eina_array_log_dom = -1; - return EINA_TRUE; -} - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Eina_Array_Group Array - * - * @brief These functions provide array management. - * - * The Array data type in Eina is designed to have a very fast access to - * its data (compared to the Eina @ref Eina_List_Group). On the other hand, - * data can be added or removed only at the end of the array. To insert - * data at any place, the Eina @ref Eina_List_Group is the correct container - * to use. - * - * To use the array data type, eina_init() must be called before any - * other array functions. When eina is no more array function is used, - * eina_shutdown() must be called to free all the resources. - * - * An array must be created with eina_array_new(). It allocated all - * the necessary data for an array. When not needed anymore, an array - * is freed with eina_array_free(). This function does not free any - * allocated memory used to store the data of each element. For that, - * just iterate over the array to free them. A convenient way to do - * that is by using #EINA_ARRAY_ITER_NEXT. An example of code is given - * in the description of this macro. - * - * @warning All the other functions do not check if the used array is - * valid or not. It's up to the user to be sure of that. It is - * designed like that for performance reasons. - * - * The usual features of an array are classic ones: to append an - * element, use eina_array_push() and to remove the last element, use - * eina_array_pop(). To retrieve the element at a given positin, use - * eina_array_data_get(). The number of elements can be retrieved with - * eina_array_count_get(). - * - * For more information, you can look at the @ref tutorial_array_page. - * - * @{ - */ - -/** - * @brief Create a new array. - * - * @param step The count of pointers to add when increasing the array size. - * @return @c NULL on failure, non @c NULL otherwise. - * - * This function creates a new array. When adding an element, the array - * allocates @p step elements. When that buffer is full, then adding - * another element will increase the buffer of @p step elements again. - * - * This function return a valid array on success, or @c NULL if memory - * allocation fails. In that case, the error is set to - * #EINA_ERROR_OUT_OF_MEMORY. - */ -EAPI Eina_Array *eina_array_new(unsigned int step) -{ - Eina_Array *array; - - eina_error_set(0); - array = malloc(sizeof(Eina_Array)); - if (!array) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY); - - array->version = EINA_ARRAY_VERSION; - array->data = NULL; - array->total = 0; - array->count = 0; - array->step = step; - - return array; -} - -/** - * @brief Free an array. - * - * @param array The array to free. - * - * This function frees @p array. It calls first eina_array_flush() then - * free the memory of the pointer. It does not free the memory - * allocated for the elements of @p array. To free them, use - * #EINA_ARRAY_ITER_NEXT. For performance reasons, there is no check - * of @p array. - */ -EAPI void eina_array_free(Eina_Array * array) -{ - eina_array_flush(array); - - EINA_SAFETY_ON_NULL_RETURN(array); - EINA_MAGIC_CHECK_ARRAY(array); - MAGIC_FREE(array); -} - -/** - * @brief Set the step of an array. - * - * @param array The array. - * @param sizeof_eina_array Should be the value returned by sizeof(Eina_Array). - * @param step The count of pointers to add when increasing the array size. - * - * This function sets the step of @p array to @p step. For performance - * reasons, there is no check of @p array. If it is @c NULL or - * invalid, the program may crash. This function should be called when - * the array is not initialized. - */ -EAPI void -eina_array_step_set(Eina_Array * array, - unsigned int sizeof_eina_array, unsigned int step) -{ - EINA_SAFETY_ON_NULL_RETURN(array); - - if (sizeof(Eina_Array) != sizeof_eina_array) { - ERR("Unknow Eina_Array size ! Got %i, expected %i !\n", - sizeof_eina_array, (int) sizeof(Eina_Array)); - /* Force memory to zero to provide a small layer of security */ - memset(array, 0, sizeof_eina_array); - return; - } - - array->version = EINA_ARRAY_VERSION; - array->data = NULL; - array->total = 0; - array->count = 0; - array->step = step; - EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY); -} - -/** - * @brief Clean an array. - * - * @param array The array to clean. - * - * This function sets the count member of @p array to 0. For - * performance reasons, there is no check of @p array. If it is - * @c NULL or invalid, the program may crash. - */ -EAPI void eina_array_clean(Eina_Array * array) -{ - EINA_SAFETY_ON_NULL_RETURN(array); - EINA_MAGIC_CHECK_ARRAY(array); - - array->count = 0; -} - -/** - * @brief Flush an array. - * - * @param array The array to flush. - * - * This function sets the count and total members of @p array to 0, - * frees and set to NULL its data member. For performance reasons, - * there is no check of @p array. If it is @c NULL or invalid, the - * program may crash. - */ -EAPI void eina_array_flush(Eina_Array * array) -{ - EINA_SAFETY_ON_NULL_RETURN(array); - EINA_MAGIC_CHECK_ARRAY(array); - - array->count = 0; - array->total = 0; - - if (!array->data) - return; - - free(array->data); - array->data = NULL; -} - -/** - * @brief Rebuild an array by specifying the data to keep. - * - * @param array The array. - * @param keep The functions which selects the data to keep. - * @param gdata The data to pass to the function keep. - * @return #EINA_TRUE on success, #EINA_FALSE oterwise. - * - * This function rebuilds @p array be specifying the elements to keep - * with the function @p keep. @p gdata is an additional data to pass - * to @p keep. For performance reasons, there is no check of @p - * array. If it is @c NULL or invalid, the program may crash. - * - * This function always return a valid array. If it wasn't able to - * remove items due to an allocation failure, it will return #EINA_FALSE - * and the error is set to #EINA_ERROR_OUT_OF_MEMORY. - */ -EAPI Eina_Bool -eina_array_remove(Eina_Array * array, Eina_Bool(*keep) (void *data, - void *gdata), - void *gdata) -{ - void **tmp; - /* WARNING: - The algorithm does exit before using unitialized data. So compiler is - giving you a false positiv here too. - */ - void *data = NULL; - unsigned int total = 0; - unsigned int limit; - unsigned int i; - - EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(keep, EINA_FALSE); - EINA_MAGIC_CHECK_ARRAY(array); - - if (array->total == 0) - return EINA_TRUE; - - for (i = 0; i < array->count; ++i) { - data = eina_array_data_get(array, i); - - if (keep(data, gdata) == EINA_FALSE) - break; - } - limit = i; - if (i < array->count) - ++i; - - for (; i < array->count; ++i) { - data = eina_array_data_get(array, i); - - if (keep(data, gdata) == EINA_TRUE) - break; - } - /* Special case all objects that need to stay are at the beginning of the array. */ - if (i == array->count) { - array->count = limit; - if (array->count == 0) { - free(array->data); - array->total = 0; - array->data = NULL; - } - - return EINA_TRUE; - } - - eina_error_set(0); - tmp = malloc(sizeof(void *) * array->total); - if (!tmp) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return EINA_FALSE; - } - - memcpy(tmp, array->data, limit * sizeof(void *)); - total = limit; - - if (i < array->count) { - tmp[total] = data; - total++; - ++i; - } - - for (; i < array->count; ++i) { - data = eina_array_data_get(array, i); - - if (keep(data, gdata)) { - tmp[total] = data; - total++; - } - } - - free(array->data); - - /* If we do not keep any object in the array, we should have exited - earlier in test (i == array->count). */ - assert(total != 0); - - array->data = tmp; - array->count = total; - return EINA_TRUE; -} - -/** - * @brief Returned a new iterator associated to an array. - * - * @param array The array. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to - * @p array. If @p array is @c NULL or the count member of @p array is - * less or equal than 0, this function returns NULL. If the memory can - * not be allocated, NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is - * set. Otherwise, a valid iterator is returned. - */ -EAPI Eina_Iterator *eina_array_iterator_new(const Eina_Array * array) -{ - Eina_Iterator_Array *it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(array, NULL); - EINA_MAGIC_CHECK_ARRAY(array); - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_Array)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(it, EINA_MAGIC_ARRAY_ITERATOR); - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->array = array; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(eina_array_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(eina_array_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(eina_array_iterator_free); - - return &it->iterator; -} - -/** - * @brief Returned a new accessor associated to an array. - * - * @param array The array. - * @return A new accessor. - * - * This function returns a newly allocated accessor associated to - * @p array. If @p array is @c NULL or the count member of @p array is - * less or equal than 0, this function returns NULL. If the memory can - * not be allocated, NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is - * set. Otherwise, a valid accessor is returned. - */ -EAPI Eina_Accessor *eina_array_accessor_new(const Eina_Array * array) -{ - Eina_Accessor_Array *ac; - - EINA_SAFETY_ON_NULL_RETURN_VAL(array, NULL); - EINA_MAGIC_CHECK_ARRAY(array); - - eina_error_set(0); - ac = calloc(1, sizeof(Eina_Accessor_Array)); - if (!ac) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(ac, EINA_MAGIC_ARRAY_ACCESSOR); - EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); - - ac->array = array; - - ac->accessor.version = EINA_ACCESSOR_VERSION; - ac->accessor.get_at = - FUNC_ACCESSOR_GET_AT(eina_array_accessor_get_at); - ac->accessor.get_container = - FUNC_ACCESSOR_GET_CONTAINER(eina_array_accessor_get_container); - ac->accessor.free = FUNC_ACCESSOR_FREE(eina_array_accessor_free); - - return &ac->accessor; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_benchmark.c b/tests/suite/ecore/src/lib/eina_benchmark.c deleted file mode 100644 index 7669121c24..0000000000 --- a/tests/suite/ecore/src/lib/eina_benchmark.c +++ /dev/null @@ -1,720 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - - -/** - * @page tutorial_benchmark_page Benchmark Tutorial - * - * The Benchmark module allows you to write easily benchmarks - * framework in a project for timing critical part and detect slow - * parts of code. In addition it automatically creates data files of - * these benchmark, as well as a gnuplot file which can display the - * comparison curves of the benchmarks. - * - * @section tutorial_benchmark_basic_usage Basic Usage - * - * To create a basic benchmark, you have to follow these steps: - * - * @li Create a new bechmark - * @li Write the functions that wraps the the functions you want to - * bechmark. - * @li Register these wrappers functions. - * @li Run the benchmark. - * @li Free the memory. - * - * Here is a basic example of bechmark which creates two functions - * that will be run. These functions just print a message. - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * - * #include <Eina.h> - * - * static - * void work1(int request) - * { - * printf ("work1 in progress... Request: %d\n", request); - * } - * - * static - * void work2(int request) - * { - * printf ("work2 in progress... Request: %d\n", request); - * } - * - * int main() - * { - * Eina_Benchmark *test; - * Eina_Array *ea; - * - * if (!eina_init()) - * return EXIT_FAILURE; - * - * test = eina_benchmark_new("test", "run"); - * if (!test) - * goto shutdown_eina; - * - * eina_benchmark_register(test, "work-1", EINA_BENCHMARK(work1), 200, 300, 10); - * eina_benchmark_register(test, "work-2", EINA_BENCHMARK(work2), 100, 150, 5); - * - * ea = eina_benchmark_run(test); - * - * eina_benchmark_free(test); - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * - * shutdown_eina: - * eina_shutdown(); - * - * return EXIT_FAILURE; - * } - * @endcode - * - * As "test", "run" are passed to eina_benchmark_new() and as the tests - * "work-1" and "work-2" are registered, the data files - * bench_test_run.work-1.data and bench_test_run.work-2.data will be - * created after the eina_benchmark_run() call. They contain four - * columns. The file bench_test_run.work-1.data contains for example: - * - * @code - * # specimen experiment time starting time ending time - * 200 23632 2852446 2876078 - * 210 6924 2883046 2889970 - * 220 6467 2895962 2902429 - * 230 6508 2908271 2914779 - * 240 6278 2920610 2926888 - * 250 6342 2932830 2939172 - * 260 6252 2944954 2951206 - * 270 6463 2956978 2963441 - * 280 6347 2969548 2975895 - * 290 6457 2981702 2988159 - * @endcode - * - * The first column (specimen) is the integer passed to the work1() - * function when the test is run. The second column (experiment time) - * is the time, in nanosecond, that work1() takes. The third and - * fourth columnd are self-explicit. - * - * You can see that the integer passed work1() starts from 200 and - * finishes at 290, with a step of 10. These values are computed withe - * last 3 values passed to eina_benchmark_register(). See the document - * of that function for the detailed behavior. - * - * The gnuplot file will be named bench_test_run.gnuplot. Just run: - * - * @code - * gnuplot bench_test_run.gnuplot - * @endcode - * - * to create the graphic of the comparison curves. The image file is - * named output_test_run.png. - * - * @section tutorial_benchmark_advanced_usage More Advanced Usage - * - * In this section, several test will be created and run. The idea is - * exactly the same than in the previous section, but with some basic - * automatic way to run all the benchmarks. The following code - * benchmarks some Eina converts functions, and some Eina containers - * types: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * #include <time.h> - * - * #include <Eina.h> - * - * static void bench_convert(Eina_Benchmark *bench); - * static void bench_container(Eina_Benchmark *bench); - * - * typedef struct _Benchmark_Case Benchmark_Case; - * - * struct _Benchmark_Case - * { - * const char *bench_case; - * void (*build)(Eina_Benchmark *bench); - * }; - * - * static const Benchmark_Case benchmarks[] = { - * { "Bench 1", bench_convert }, - * { "Bench 2", bench_container }, - * { NULL, NULL } - * }; - * - * static - * void convert1(int request) - * { - * char tmp[128]; - * int i; - * - * srand(time(NULL)); - * - * for (i = 0; i < request; ++i) - * eina_convert_itoa(rand(), tmp); - * } - * - * static - * void convert2(int request) - * { - * char tmp[128]; - * int i; - * - * srand(time(NULL)); - * - * for (i = 0; i < request; ++i) - * eina_convert_xtoa(rand(), tmp); - * } - * - * static void - * bench_convert(Eina_Benchmark *bench) - * { - * eina_benchmark_register(bench, "convert-1", EINA_BENCHMARK(convert1), 200, 400, 10); - * eina_benchmark_register(bench, "convert-2", EINA_BENCHMARK(convert2), 200, 400, 10); - * } - * - * static - * void array(int request) - * { - * Eina_Array *array; - * Eina_Array_Iterator it; - * int *data; - * int i; - * - * srand(time(NULL)); - * - * array = eina_array_new(64); - * - * for (i = 0; i < request; ++i) - * { - * data = (int *)malloc(sizeof(int)); - * if (!data) continue; - * *data = rand(); - * eina_array_push(array, data); - * } - * - * EINA_ARRAY_ITER_NEXT(array, i, data, it) - * free(data); - * - * eina_array_free(array); - * } - * - * static - * void list(int request) - * { - * Eina_List *l = NULL; - * int *data; - * int i; - * - * srand(time(NULL)); - * - * for (i = 0; i < request; ++i) - * { - * data = (int *)malloc(sizeof(int)); - * if (!data) continue; - * *data = rand(); - * l = eina_list_prepend(l, data); - * } - * - * while (l) - * { - * free(eina_list_data_get(l)); - * l = eina_list_remove_list(l, l); - * } - * } - * - * static void - * bench_container(Eina_Benchmark *bench) - * { - * eina_benchmark_register(bench, "array", EINA_BENCHMARK(array), 200, 300, 10); - * eina_benchmark_register(bench, "list", EINA_BENCHMARK(list), 200, 300, 10); - * } - * - * int main() - * { - * Eina_Benchmark *test; - * Eina_Array *ea; - * unsigned int i; - * - * if (!eina_init()) - * return EXIT_FAILURE; - * - * for (i = 0; benchmarks[i].bench_case != NULL; ++i) - * { - * test = eina_benchmark_new(benchmarks[i].bench_case, "Benchmark example"); - * if (!test) - * continue; - * - * benchmarks[i].build(test); - * - * ea = eina_benchmark_run(test); - * - * eina_benchmark_free(test); - * } - * - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - * gnuplot can be used to see how are performed the convert functions - * together, as well as how are performed the containers. So it is now - * easy to see that the hexadecimal convert function is faster than - * the decimal one, and that arrays are faster than lists. - * - * You can improve all that by executing automatically gnuplot in your - * program, or integrate the Eina benchmark framework in an autotooled - * project. See that - * <a href="http://trac.enlightenment.org/e/wiki/AutotoolsIntegration#Benchmark">page</a> - * for more informations. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#elif defined __GNUC__ -#define alloca __builtin_alloca -#elif defined _AIX -#define alloca __alloca -#elif defined _MSC_VER -#include <malloc.h> -#define alloca _alloca -#else -#include <stddef.h> -#ifdef __cplusplus -extern "C" -#endif -void *alloca(size_t); -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_log.h" -#include "eina_benchmark.h" -#include "eina_inlist.h" -#include "eina_list.h" -#include "eina_counter.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -#define EINA_BENCHMARK_FILENAME_MASK "bench_%s_%s.gnuplot" -#define EINA_BENCHMARK_DATA_MASK "bench_%s_%s.%s.data" - -typedef struct _Eina_Run Eina_Run; -struct _Eina_Run { - EINA_INLIST; - - Eina_Benchmark_Specimens cb; - const char *name; - int start; - int end; - int step; -}; - -struct _Eina_Benchmark { - const char *name; - const char *run; - - Eina_Inlist *runs; - Eina_List *names; -}; - -static int _eina_benchmark_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_benchmark_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_benchmark_log_dom, __VA_ARGS__) - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the benchmark module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the benchmark module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_benchmark_init(void) -{ - _eina_benchmark_log_dom = - eina_log_domain_register("eina_benchmark", - EINA_LOG_COLOR_DEFAULT); - if (_eina_benchmark_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_benchmark"); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the benchmark module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the benchmark module set up by - * eina_benchmark_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_benchmark_shutdown(void) -{ - eina_log_domain_unregister(_eina_benchmark_log_dom); - _eina_benchmark_log_dom = -1; - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Benchmark_Group Benchmark - * - * These functions allow you to add benchmark framework in a project - * for timing critical part and detect slow parts of code. It is used - * in Eina to compare the time used by eina, glib, evas and ecore data - * types. - * - * To use the benchmark module, Eina must be initialized with - * eina_init() and later shut down with eina_shutdown(). A benchmark - * is created with eina_benchmark_new() and freed with - * eina_benchmark_free(). - * - * eina_benchmark_register() adds a test to a benchmark. That test can - * be run a certain amount of times. Adding more than one test to be - * executed allows the comparison between several parts of a program, - * or different implementations. - * - * eina_benchmark_run() runs all the tests registered with - * eina_benchmark_register(). The amount of time of each test is - * written in a gnuplot file. - * - * For more information, you can look at the @ref tutorial_benchmark_page. - * - * @{ - */ - -/** - * @brief Create a new array. - * - * @param name The name of the benchmark. - * @param run The name of the run. - * @return @c NULL on failure, non @c NULL otherwise. - * - * This function creates a new benchmark. @p name and @p run are used - * to name the gnuplot file that eina_benchmark_run() will create. - * - * This function return a valid benchmark on success, or @c NULL if - * memory allocation fails. In that case, the error is set to - * #EINA_ERROR_OUT_OF_MEMORY. - * - * When the new module is not needed anymore, use - * eina_benchmark_free() to free the allocated memory. - */ -EAPI Eina_Benchmark *eina_benchmark_new(const char *name, const char *run) -{ - Eina_Benchmark *new; - - eina_error_set(0); - new = calloc(1, sizeof(Eina_Benchmark)); - if (!new) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - new->name = name; - new->run = run; - - return new; -} - -/** - * @brief Free a benchmark object. - * - * @param bench The benchmark to free. - * - * This function removes all the benchmark tests that have been - * registered and frees @p bench. If @p bench is @c NULL, this - * function returns immediately. - */ -EAPI void eina_benchmark_free(Eina_Benchmark * bench) -{ - Eina_Array *names; - - if (!bench) - return; - - while (bench->runs) { - Eina_Run *run = (Eina_Run *) bench->runs; - - bench->runs = eina_inlist_remove(bench->runs, bench->runs); - free(run); - } - - EINA_LIST_FREE(bench->names, names) { - Eina_Array_Iterator it; - char *tmp; - unsigned int i; - - EINA_ARRAY_ITER_NEXT(names, i, tmp, it) - free(tmp); - - eina_array_free(names); - } - - free(bench); -} - -/** - * @brief Add a test to a benchmark. - * - * @param bench The benchmark. - * @param name The name of the test. - * @param bench_cb The test function to be called. - * @param count_start The start data to be passed to @p bench_cb. - * @param count_end The end data to be passed to @p bench_cb. - * @param count_step The step data to be passed to @p bench_cb. - * - * This function adds the test named @p name to @p benchmark. @p - * bench_cb is the function called when the test is executed. That - * test can be executed a certain amount of time. @p start, @p end and - * @p step define a loop with a step increment. The integer that is - * increasing by @p step from @p start to @p end is passed to @p - * bench_cb when eina_benchmark_run() is called. - * - * If @p bench is @c NULL, this function returns imediatly. If the - * allocation of the memory of the test to add fails, the error is set - * to #EINA_ERROR_OUT_OF_MEMORY. - */ -EAPI Eina_Bool -eina_benchmark_register(Eina_Benchmark * bench, - const char *name, - Eina_Benchmark_Specimens bench_cb, - int count_start, int count_end, int count_step) -{ - Eina_Run *run; - - if (!bench) - return EINA_FALSE; - - if (count_step == 0) - return EINA_FALSE; - - eina_error_set(0); - run = calloc(1, sizeof(Eina_Run)); - if (!run) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return EINA_FALSE; - } - - run->cb = bench_cb; - run->name = name; - run->start = count_start; - run->end = count_end; - run->step = count_step; - - bench->runs = - eina_inlist_append(bench->runs, EINA_INLIST_GET(run)); - - return EINA_TRUE; -} - -/** - * @brief Run the benchmark tests that have been registered. - * - * @param bench The benchmark. - * @return The list of names of the test files. - * - * This function runs all the tests that as been registered with - * eina_benchmark_register() and save the result in a gnuplot - * file. The name of the file has the following format: - * - * @code - * bench_[name]_[run]%s.gnuplot - * @endcode - * - * where [name] and [run] are the values passed to - * eina_benchmark_new(). - * - * Each registered test is executed and timed. The time is written to - * the gnuplot file. The number of times each test is executed is - * controlled by the parameters passed to eina_benchmark_register(). - * - * If @p bench is @c NULL, this functions returns @c NULL - * immediately. Otherwise, it returns the list of the names of each - * test. - */ -EAPI Eina_Array *eina_benchmark_run(Eina_Benchmark * bench) -{ - FILE *main_script; - FILE *current_data; - Eina_Array *ea; - Eina_Run *run; - char *buffer; - Eina_Bool first = EINA_FALSE; - size_t length; - - if (!bench) - return NULL; - - length = - strlen(EINA_BENCHMARK_FILENAME_MASK) + strlen(bench->name) + - strlen(bench->run); - - buffer = alloca(sizeof(char) * length); - if (!buffer) - return NULL; - - snprintf(buffer, - length, - EINA_BENCHMARK_FILENAME_MASK, bench->name, bench->run); - - main_script = fopen(buffer, "w"); - if (!main_script) - return NULL; - - ea = eina_array_new(16); - if (!ea) { - fclose(main_script); - return NULL; - } - - eina_array_push(ea, strdup(buffer)); - - fprintf(main_script, - "set autoscale # scale axes automatically\n" - "unset log # remove any log-scaling\n" - "unset label # remove any previous labels\n" - "set xtic auto # set xtics automatically\n" - "set ytic auto # set ytics automatically\n" -/* "set logscale y\n" */ - "set terminal png size 1024,768\n" - "set output \"output_%s_%s.png\"\n" - "set title \"%s %s\n" - "set xlabel \"tests\"\n" - "set ylabel \"time\"\n" - "plot ", bench->name, bench->run, bench->name, bench->run); - - EINA_INLIST_FOREACH(bench->runs, run) { - Eina_Counter *counter; - char *result; - size_t tmp; - int i; - - tmp = - strlen(EINA_BENCHMARK_DATA_MASK) + - strlen(bench->name) + strlen(bench->run) + - strlen(run->name); - if (tmp > length) { - buffer = alloca(sizeof(char) * tmp); - length = tmp; - } - - snprintf(buffer, - length, - EINA_BENCHMARK_DATA_MASK, - bench->name, bench->run, run->name); - - current_data = fopen(buffer, "w"); - if (!current_data) - continue; - - eina_array_push(ea, strdup(buffer)); - - counter = eina_counter_new(run->name); - - for (i = run->start; i < run->end; i += run->step) { - fprintf(stderr, "Run %s: %i\n", run->name, i); - eina_counter_start(counter); - - run->cb(i); - - eina_counter_stop(counter, i); - } - - result = eina_counter_dump(counter); - if (result) { - fprintf(current_data, "%s", result); - free(result); - } - - eina_counter_free(counter); - - fclose(current_data); - - if (first == EINA_FALSE) - first = EINA_TRUE; - else - fprintf(main_script, ", \\\n"); - - fprintf(main_script, - "\"%s\" using 1:2 title \'%s\' with line", - buffer, run->name); - } - - fprintf(main_script, "\n"); - - fclose(main_script); - - bench->names = eina_list_append(bench->names, ea); - - return ea; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_binshare.c b/tests/suite/ecore/src/lib/eina_binshare.c deleted file mode 100644 index 9754f76d94..0000000000 --- a/tests/suite/ecore/src/lib/eina_binshare.c +++ /dev/null @@ -1,193 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, - * Jorge Luis Zapata Muga, - * Cedric Bail, - * Gustavo Sverzut Barbieri - * Tom Hacohen - * - * 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 <https://www.gnu.org/licenses/>. - - */ -/** - * @page tutorial_binshare_page Binary Share Tutorial - * - * Should call eina_binshare_init() before usage and eina_binshare_shutdown() after. - * to be written... - * - */ - -#include "eina_share_common.h" -#include "eina_unicode.h" -#include "eina_private.h" -#include "eina_binshare.h" - -/* The actual share */ -static Eina_Share *binshare_share; -static const char EINA_MAGIC_BINSHARE_NODE_STR[] = "Eina Binshare Node"; - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the share_common module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -EAPI Eina_Bool eina_binshare_init(void) -{ - return eina_share_common_init(&binshare_share, - EINA_MAGIC_BINSHARE_NODE, - EINA_MAGIC_BINSHARE_NODE_STR); -} - -/** - * @internal - * @brief Shut down the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the share_common module set up by - * eina_share_common_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -EAPI Eina_Bool eina_binshare_shutdown(void) -{ - Eina_Bool ret; - ret = eina_share_common_shutdown(&binshare_share); - return ret; -} - -/*============================================================================* -* API * -*============================================================================*/ -/** - * @addtogroup Eina_Binshare_Group Binary Share - * - * These functions allow you to store one copy of an object, and use it - * throughout your program. - * - * This is a method to reduce the number of duplicated objects kept in - * memory. - * - * For more information, you can look at the @ref tutorial_binshare_page. - * - * @{ - */ - -/** - * @brief Note that the given object has lost an instance. - * - * @param obj object The given object. - * - * This function decreases the reference counter associated to @p obj - * if it exists. If that counter reaches 0, the memory associated to - * @p obj is freed. If @p obj is NULL, the function returns - * immediately. - * - * Note that if the given pointer is not shared or NULL, bad things - * will happen, likely a segmentation fault. - */ -EAPI void eina_binshare_del(const void *obj) -{ - if (!obj) - return; - - eina_share_common_del(binshare_share, obj); -} - -/** - * @brief Retrieve an instance of an object for use in a program. - * - * @param obj The binary object to retrieve an instance of. - * @param olen The byte size - * @return A pointer to an instance of the object on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p obj. If @p obj is - * @c NULL, then @c NULL is returned. If @p obj is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the objects to be searched and a duplicated object - * of @p obj is returned. - * - * This function does not check object size, but uses the - * exact given size. This can be used to share part of a larger - * object or subobject. - * - * @see eina_binshare_add() - */ -EAPI const void *eina_binshare_add_length(const void *obj, - unsigned int olen) -{ - return eina_share_common_add_length(binshare_share, - obj, (olen) * sizeof(char), 0); -} - -/** - * Increment references of the given shared object. - * - * @param obj The shared object. - * @return A pointer to an instance of the object on success. - * @c NULL on failure. - * - * This is similar to eina_share_common_add(), but it's faster since it will - * avoid lookups if possible, but on the down side it requires the parameter - * to be shared before, in other words, it must be the return of a previous - * eina_binshare_add(). - * - * There is no unref since this is the work of eina_binshare_del(). - */ -EAPI const void *eina_binshare_ref(const void *obj) -{ - return eina_share_common_ref(binshare_share, obj); -} - -/** - * @brief Note that the given object @b must be shared. - * - * @param obj the shared object to know the length. It is safe to - * give NULL, in that case -1 is returned. - * - * This function is a cheap way to known the length of a shared - * object. Note that if the given pointer is not shared, bad - * things will happen, likely a segmentation fault. If in doubt, try - * strlen(). - */ -EAPI int eina_binshare_length(const void *obj) -{ - return eina_share_common_length(binshare_share, obj); -} - -/** - * @brief Dump the contents of the share_common. - * - * This function dumps all objects in the share_common to stdout with a - * DDD: prefix per line and a memory usage summary. - */ -EAPI void eina_binshare_dump(void) -{ - eina_share_common_dump(binshare_share, NULL, 0); -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_chained_mempool.c b/tests/suite/ecore/src/lib/eina_chained_mempool.c deleted file mode 100644 index e79d5078d8..0000000000 --- a/tests/suite/ecore/src/lib/eina_chained_mempool.c +++ /dev/null @@ -1,345 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008-2010 Cedric BAIL, Vincent Torri - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#ifdef EFL_HAVE_POSIX_THREADS -#include <pthread.h> -#endif - -#ifdef EFL_HAVE_WIN32_THREADS -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#endif - -#include "eina_inlist.h" -#include "eina_error.h" -#include "eina_module.h" -#include "eina_mempool.h" -#include "eina_trash.h" - -#include "eina_private.h" - -#ifdef DEBUG -#include "eina_log.h" - -static int _eina_mempool_log_dom = -1; - -#ifdef INF -#undef INF -#endif -#define INF(...) EINA_LOG_DOM_INFO(_eina_mempool_log_dom, __VA_ARGS__) -#endif - -typedef struct _Chained_Mempool Chained_Mempool; -struct _Chained_Mempool { - Eina_Inlist *first; - const char *name; - int item_alloc; - int pool_size; - int alloc_size; - int group_size; - int usage; -#ifdef EFL_HAVE_THREADS -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_t mutex; -#else - HANDLE mutex; -#endif -#endif -}; - -typedef struct _Chained_Pool Chained_Pool; -struct _Chained_Pool { - EINA_INLIST; - Eina_Trash *base; - int usage; -}; - -static inline Chained_Pool *_eina_chained_mp_pool_new(Chained_Mempool * - pool) -{ - Chained_Pool *p; - unsigned char *ptr; - int i; - - eina_error_set(0); - p = malloc(pool->alloc_size); - if (!p) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - ptr = - (unsigned char *) p + - eina_mempool_alignof(sizeof(Chained_Pool)); - p->usage = 0; - p->base = NULL; - for (i = 0; i < pool->pool_size; ++i, ptr += pool->item_alloc) - eina_trash_push(&p->base, ptr); - return p; -} - -static inline void _eina_chained_mp_pool_free(Chained_Pool * p) -{ - free(p); -} - -static void *eina_chained_mempool_malloc(void *data, - __UNUSED__ unsigned int size) -{ - Chained_Mempool *pool = data; - Chained_Pool *p = NULL; - void *mem; - -#ifdef EFL_HAVE_THREADS -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_lock(&pool->mutex); -#else - WaitForSingleObject(pool->mutex, INFINITE); -#endif -#endif - - // look 4 pool from 2nd bucket on - EINA_INLIST_FOREACH(pool->first, p) { - // base is not NULL - has a free slot - if (p->base) { - pool->first = - eina_inlist_demote(pool->first, - EINA_INLIST_GET(p)); - break; - } - } - - // we have reached the end of the list - no free pools - if (!p) { - p = _eina_chained_mp_pool_new(pool); - if (!p) { -#ifdef EFL_HAVE_PTHREAD -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_unlock(&pool->mutex); -#else - ReleaseMutex(pool->mutex); -#endif -#endif - return NULL; - } - - pool->first = - eina_inlist_prepend(pool->first, EINA_INLIST_GET(p)); - } - // Request a free pointer - mem = eina_trash_pop(&p->base); - // move to end - it just filled up - if (!p->base) - pool->first = - eina_inlist_demote(pool->first, EINA_INLIST_GET(p)); - - p->usage++; - pool->usage++; - -#ifdef EFL_HAVE_THREADS -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_unlock(&pool->mutex); -#else - ReleaseMutex(pool->mutex); -#endif -#endif - - return mem; -} - -static void eina_chained_mempool_free(void *data, void *ptr) -{ - Chained_Mempool *pool = data; - Chained_Pool *p; - void *pmem; - int psize; - - psize = pool->group_size; - // look 4 pool - -#ifdef EFL_HAVE_THREADS -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_lock(&pool->mutex); -#else - WaitForSingleObject(pool->mutex, INFINITE); -#endif -#endif - - EINA_INLIST_FOREACH(pool->first, p) { - // pool mem base - pmem = - (void *) (((unsigned char *) p) + - sizeof(Chained_Pool)); - // is it in pool mem? - if ((ptr >= pmem) && - ((unsigned char *) ptr < - (((unsigned char *) pmem) + psize))) { - // freed node points to prev free node - eina_trash_push(&p->base, ptr); - // next free node is now the one we freed - p->usage--; - pool->usage--; - if (p->usage == 0) { - // free bucket - pool->first = - eina_inlist_remove(pool->first, - EINA_INLIST_GET(p)); - _eina_chained_mp_pool_free(p); - } else - // move to front - pool->first = - eina_inlist_promote(pool->first, - EINA_INLIST_GET - (p)); - - break; - } - } - -#ifdef EFL_HAVE_THREADS -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_unlock(&pool->mutex); -#else - ReleaseMutex(pool->mutex); -#endif -#endif -} - -static void *eina_chained_mempool_realloc(__UNUSED__ void *data, - __UNUSED__ void *element, - __UNUSED__ unsigned int size) -{ - return NULL; -} - -static void *eina_chained_mempool_init(const char *context, - __UNUSED__ const char *option, - va_list args) -{ - Chained_Mempool *mp; - int item_size; - size_t length; - - length = context ? strlen(context) + 1 : 0; - - mp = calloc(1, sizeof(Chained_Mempool) + length); - if (!mp) - return NULL; - - item_size = va_arg(args, int); - mp->pool_size = va_arg(args, int); - - if (length) { - mp->name = (const char *) (mp + 1); - memcpy((char *) mp->name, context, length); - } - - mp->item_alloc = eina_mempool_alignof(item_size); - mp->group_size = mp->item_alloc * mp->pool_size; - mp->alloc_size = - mp->group_size + eina_mempool_alignof(sizeof(Chained_Pool)); - -#ifdef EFL_HAVE_THREADS -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_init(&mp->mutex, NULL); -#else - mp->mutex = CreateMutex(NULL, FALSE, NULL); -#endif -#endif - - return mp; -} - -static void eina_chained_mempool_shutdown(void *data) -{ - Chained_Mempool *mp; - - mp = (Chained_Mempool *) data; - - while (mp->first) { - Chained_Pool *p = (Chained_Pool *) mp->first; - -#ifdef DEBUG - if (p->usage > 0) - INF("Bad news we are destroying not an empty mempool [%s]\n", mp->name); - -#endif - - mp->first = eina_inlist_remove(mp->first, mp->first); - _eina_chained_mp_pool_free(p); - } - -#ifdef EFL_HAVE_THREADS -#ifdef EFL_HAVE_POSIX_THREADS - pthread_mutex_destroy(&mp->mutex); -#else - CloseHandle(mp->mutex); -#endif -#endif - - free(mp); -} - -static Eina_Mempool_Backend _eina_chained_mp_backend = { - "chained_mempool", - &eina_chained_mempool_init, - &eina_chained_mempool_free, - &eina_chained_mempool_malloc, - &eina_chained_mempool_realloc, - NULL, - NULL, - &eina_chained_mempool_shutdown -}; - -Eina_Bool chained_init(void) -{ -#ifdef DEBUG - _eina_mempool_log_dom = eina_log_domain_register("eina_mempool", - EINA_LOG_COLOR_DEFAULT); - if (_eina_mempool_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_mempool"); - return EINA_FALSE; - } -#endif - return eina_mempool_register(&_eina_chained_mp_backend); -} - -void chained_shutdown(void) -{ - eina_mempool_unregister(&_eina_chained_mp_backend); -#ifdef DEBUG - eina_log_domain_unregister(_eina_mempool_log_dom); - _eina_mempool_log_dom = -1; -#endif -} - -#ifndef EINA_STATIC_BUILD_CHAINED_POOL - -EINA_MODULE_INIT(chained_init); -EINA_MODULE_SHUTDOWN(chained_shutdown); - -#endif /* ! EINA_STATIC_BUILD_CHAINED_POOL */ diff --git a/tests/suite/ecore/src/lib/eina_convert.c b/tests/suite/ecore/src/lib/eina_convert.c deleted file mode 100644 index c4a2523eb9..0000000000 --- a/tests/suite/ecore/src/lib/eina_convert.c +++ /dev/null @@ -1,746 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008 Cedric BAIL, Vincent Torri - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <math.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_log.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_convert.h" -#include "eina_fp.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static const char look_up_table[] = { '0', '1', '2', '3', '4', - '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f' -}; - -static int _eina_convert_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_convert_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_convert_log_dom, __VA_ARGS__) - -#define HEXA_TO_INT(Hexa) (Hexa >= 'a') ? Hexa - 'a' + 10 : Hexa - '0' - -static inline void reverse(char s[], int length) -{ - int i, j; - char c; - - for (i = 0, j = length - 1; i < j; i++, j--) { - c = s[i]; - s[i] = s[j]; - s[j] = c; - } -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -EAPI Eina_Error EINA_ERROR_CONVERT_P_NOT_FOUND = 0; -EAPI Eina_Error EINA_ERROR_CONVERT_0X_NOT_FOUND = 0; -EAPI Eina_Error EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH = 0; - -static const char EINA_ERROR_CONVERT_0X_NOT_FOUND_STR[] = - "Error during string conversion to float, First '0x' was not found."; -static const char EINA_ERROR_CONVERT_P_NOT_FOUND_STR[] = - "Error during string conversion to float, First 'p' was not found."; -static const char EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH_STR[] = - "Error outrun string limit during conversion string conversion to float."; - -/** - * @endcond - */ - -/** - * @internal - * @brief Initialize the convert module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the convert module of Eina. It is called by - * eina_init(). - * - * This function sets up the error module of Eina and registers the - * errors #EINA_ERROR_CONVERT_0X_NOT_FOUND, - * #EINA_ERROR_CONVERT_P_NOT_FOUND and - * #EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH. - * - * @see eina_init() - */ -Eina_Bool eina_convert_init(void) -{ - _eina_convert_log_dom = eina_log_domain_register("eina_convert", - EINA_LOG_COLOR_DEFAULT); - if (_eina_convert_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_convert"); - return EINA_FALSE; - } -#define EEMR(n) n = eina_error_msg_static_register(n ## _STR) - EEMR(EINA_ERROR_CONVERT_0X_NOT_FOUND); - EEMR(EINA_ERROR_CONVERT_P_NOT_FOUND); - EEMR(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH); -#undef EEMR - - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the convert module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the convert module set up by - * eina_convert_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_convert_shutdown(void) -{ - eina_log_domain_unregister(_eina_convert_log_dom); - _eina_convert_log_dom = -1; - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Convert_Group Convert - * - * These functions allow you to convert integer or real numbers to - * string or conversely. - * - * To use these functions, you have to call eina_init() - * first, and eina_shutdown() when eina is not used anymore. - * - * @section Eina_Convert_From_Integer_To_Sring Conversion from integer to string - * - * To convert an integer to a string in the decimal base, - * eina_convert_itoa() should be used. If the hexadecimal base is - * wanted, eina_convert_xtoa() should be used. They all need a bufffer - * sufficiently large to store all the cyphers. - * - * Here is an example of use: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * - * #include <Eina.h> - * - * int main(void) - * { - * char tmp[128]; - * - * if (!eina_init()) - * { - * printf ("Error during the initialization of eina.\n"); - * return EXIT_FAILURE; - * } - * - * eina_convert_itoa(45, tmp); - * printf("value: %s\n", tmp); - - * eina_convert_xtoa(0xA1, tmp); - * printf("value: %s\n", tmp); - * - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - * Compile this code with the following command: - * - * @code - * gcc -Wall -o test_eina_convert test_eina.c `pkg-config --cflags --libs eina` - * @endcode - * - * @note - * The alphabetical cyphers are in lower case. - * - * @section Eina_Convert_Double Conversion double / string - * - * To convert a double to a string, eina_convert_dtoa() should be - * used. Like with the integer functions, a buffer must be used. The - * resulting string ghas the following format (which is the result - * obtained with snprintf() and the @%a modifier): - * - * @code - * [-]0xh.hhhhhp[+-]e - * @endcode - * - * To convert a string to a double, eina_convert_atod() should be - * used. The format of the string must be as above. Then, the double - * has the following mantiss and exponent: - * - * @code - * mantiss : [-]hhhhhh - * exponent : 2^([+-]e - 4 * n) - * @endcode - * - * with n being number of cypers after the point in the string - * format. To obtain the double number from the mantiss and exponent, - * use ldexp(). - * - * Here is an example of use: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * #include <math.h> - * - * #include <Eina.h> - * - * int main(void) - * { - * char tmp[128]; - * long long int m = 0; - * long int e = 0; - * double r; - * - * if (!eina_init()) - * { - * printf ("Error during the initialization of eina.\n"); - * return EXIT_FAILURE; - * } - * - * printf("initial value : 40.56\n"); - * eina_convert_dtoa(40.56, tmp); - * printf("result dtoa : %s\n", tmp); - - * eina_convert_atod(tmp, 128, &m, &e); - * r = ldexp((double)m, e); - * printf("result atod : %f\n", r); - * - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - * Compile this code with the following command: - * - * @code - * gcc -Wall -o test_eina_convert test_eina.c `pkg-config --cflags --libs eina` -lm - * @endcode - * - * @{ - */ - -/* - * Come from the second edition of The C Programming Language ("K&R2") on page 64 - */ - -/** - * @brief Convert an integer number to a string in decimal base. - * - * @param n The integer to convert. - * @param s The buffer to store the converted integer. - * @return The length of the string, including the nul terminated - * character. - * - * This function converts @p n to a nul terminated string. The - * converted string is in decimal base. As no check is done, @p s must - * be a buffer that is sufficiently large to store the integer. - * - * The returned value is the length of the string, including the nul - * terminated character. - */ -EAPI int eina_convert_itoa(int n, char *s) -{ - int i = 0; - int r = 0; - - EINA_SAFETY_ON_NULL_RETURN_VAL(s, 0); - - if (n < 0) { - n = -n; - *s++ = '-'; - r = 1; - } - - do { - s[i++] = n % 10 + '0'; - } while ((n /= 10) > 0); - - s[i] = '\0'; - - reverse(s, i); - - return i + r; -} - -/** - * @brief Convert an integer number to a string in hexadecimal base. - * - * @param n The integer to convert. - * @param s The buffer to store the converted integer. - * @return The length of the string, including the nul terminated - * character. - * - * This function converts @p n to a nul terminated string. The - * converted string is in hexadecimal base and the alphabetical - * cyphers are in lower case. As no check is done, @p s must be a - * buffer that is sufficiently large to store the integer. - * - * The returned value is the length of the string, including the nul - * terminated character. - */ -EAPI int eina_convert_xtoa(unsigned int n, char *s) -{ - int i; - - EINA_SAFETY_ON_NULL_RETURN_VAL(s, 0); - - i = 0; - do { - s[i++] = look_up_table[n & 0xF]; - } while ((n >>= 4) > 0); - - s[i] = '\0'; - - reverse(s, i); - - return i; -} - -/** - * @brief Convert a string to a double. - * - * @param src The string to convert. - * @param length The length of the string. - * @param m The mantisse. - * @param e The exponent. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function converts the string @p s of length @p length that - * represent a double in hexadecimal base to a double. It is used to - * replace the use of snprintf() with the \%a modifier, which is - * missing on some platform (like Windows (tm) or OpenBSD). - * - * The string must have the following format: - * - * @code - * [-]0xh.hhhhhp[+-]e - * @endcode - * - * where the h are the hexadecimal cyphers of the mantiss and e the - * exponent (a decimal number). If n is the number of cypers after the - * point, the returned mantiss and exponents are: - * - * @code - * mantiss : [-]hhhhhh - * exponent : 2^([+-]e - 4 * n) - * @endcode - * - * The mantiss and exponent are stored in the buffers pointed - * respectively by @p m and @p e. - * - * If the string is invalid, the error is set to: - * - * @li #EINA_ERROR_CONVERT_0X_NOT_FOUND if no 0x is found, - * @li #EINA_ERROR_CONVERT_P_NOT_FOUND if no p is found, - * @li #EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH if @p length is not - * correct. - * - * In those cases, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -EAPI Eina_Bool -eina_convert_atod(const char *src, int length, long long *m, long *e) -{ - const char *str = src; - long long mantisse; - long exponent; - int nbr_decimals = 0; - int sign = 1; - - EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(e, EINA_FALSE); - - if (length <= 0) - goto on_length_error; - - /* Compute the mantisse. */ - if (*str == '-') { - sign = -1; - str++; - length--; - } - - if (length <= 2) - goto on_length_error; - - if (strncmp(str, "0x", 2)) { - eina_error_set(EINA_ERROR_CONVERT_0X_NOT_FOUND); - DBG("'0x' not found in '%s'", src); - return EINA_FALSE; - } - - str += 2; - length -= 2; - - mantisse = HEXA_TO_INT(*str); - - str++; - length--; - if (length <= 0) - goto on_length_error; - - if (*str == '.') - for (str++, length--; - length > 0 && *str != 'p'; - ++str, --length, ++nbr_decimals) { - mantisse <<= 4; - mantisse += HEXA_TO_INT(*str); - } - - if (sign < 0) - mantisse = -mantisse; - - /* Compute the exponent. */ - if (*str != 'p') { - eina_error_set(EINA_ERROR_CONVERT_P_NOT_FOUND); - DBG("'p' not found in '%s'", src); - return EINA_FALSE; - } - - sign = +1; - - str++; - length--; - if (length <= 0) - goto on_length_error; - - if (strchr("-+", *str)) { - sign = (*str == '-') ? -1 : +1; - - str++; - length--; - } - - for (exponent = 0; length > 0 && *str != '\0'; ++str, --length) { - exponent *= 10; - exponent += *str - '0'; - } - - if (length < 0) - goto on_length_error; - - if (sign < 0) - exponent = -exponent; - - *m = mantisse; - *e = exponent - (nbr_decimals << 2); - - return EINA_TRUE; - - on_length_error: - eina_error_set(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH); - return EINA_FALSE; -} - -/** - * @brief Convert a double to a string. - * - * @param d The double to convert. - * @param des The destination buffer to store the converted double. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function converts the double @p d to a string. The string is - * stored in the buffer pointed by @p des and must be sufficiently - * large to contain the converted double. The returned string is nul - * terminated and has the following format: - * - * @code - * [-]0xh.hhhhhp[+-]e - * @endcode - * - * where the h are the hexadecimal cyphers of the mantiss and e the - * exponent (a decimal number). - * - * The returned value is the length of the string, including the nul - * character. - */ -EAPI int eina_convert_dtoa(double d, char *des) -{ - int length = 0; - int p; - int i; - - EINA_SAFETY_ON_NULL_RETURN_VAL(des, EINA_FALSE); - - if (d < 0.0) { - *(des++) = '-'; - d = -d; - length++; - } - - d = frexp(d, &p); - - if (p) { - d *= 2; - p -= 1; - } - - *(des++) = '0'; - *(des++) = 'x'; - *(des++) = look_up_table[(size_t) d]; - *(des++) = '.'; - length += 4; - - for (i = 0; i < 16; i++, length++) { - d -= floor(d); - d *= 16; - *(des++) = look_up_table[(size_t) d]; - } - - while (*(des - 1) == '0') { - des--; - length--; - } - - if (*(des - 1) == '.') { - des--; - length--; - } - - *(des++) = 'p'; - if (p < 0) { - *(des++) = '-'; - p = -p; - } else - *(des++) = '+'; - - length += 2; - - return length + eina_convert_itoa(p, des); -} - -/** - * @brief Convert a 32.32 fixed point number to a string. - * - * @param fp The fixed point number to convert. - * @param des The destination buffer to store the converted fixed point number. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function converts the 32.32 fixed point number @p fp to a - * string. The string is stored in the buffer pointed by @p des and - * must be sufficiently large to contain the converted fixed point - * number. The returned string is terminated and has the following - * format: - * - * @code - * [-]0xh.hhhhhp[+-]e - * @endcode - * - * where the h are the hexadecimal cyphers of the mantiss and e the - * exponent (a decimal number). - * - * The returned value is the length of the string, including the nul - * character. - * - * @note The code is the same than eina_convert_dtoa() except that it - * implements the frexp() function for fixed point numbers and does - * some optimisations. - */ -EAPI int eina_convert_fptoa(Eina_F32p32 fp, char *des) -{ - int length = 0; - int p = 0; - int i; - - EINA_SAFETY_ON_NULL_RETURN_VAL(des, EINA_FALSE); - - if (fp == 0) { - memcpy(des, "0x0p+0", 7); - return 7; - } - - if (fp < 0) { - *(des++) = '-'; - fp = -fp; - length++; - } - - /* fp >= 1 */ - if (fp >= 0x0000000100000000LL) - while (fp >= 0x0000000100000000LL) { - p++; - /* fp /= 2 */ - fp >>= 1; - } /* fp < 0.5 */ - else if (fp < 0x80000000) - while (fp < 0x80000000) { - p--; - /* fp *= 2 */ - fp <<= 1; - } - - if (p) { - p--; - /* fp *= 2 */ - fp <<= 1; - } - - *(des++) = '0'; - *(des++) = 'x'; - *(des++) = look_up_table[fp >> 32]; - *(des++) = '.'; - length += 4; - - for (i = 0; i < 16; i++, length++) { - fp &= 0x00000000ffffffffLL; - fp <<= 4; /* fp *= 16 */ - *(des++) = look_up_table[fp >> 32]; - } - - while (*(des - 1) == '0') { - des--; - length--; - } - - if (*(des - 1) == '.') { - des--; - length--; - } - - *(des++) = 'p'; - if (p < 0) { - *(des++) = '-'; - p = -p; - } else - *(des++) = '+'; - - length += 2; - - return length + eina_convert_itoa(p, des); -} - -/** - * @brief Convert a string to a 32.32 fixed point number. - * - * @param src The string to convert. - * @param length The length of the string. - * @param fp The fixed point number. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function converts the string @p src of length @p length that - * represent a double in hexadecimal base to a 32.32 fixed point - * number stored in @p fp. The function always tries to convert the - * string with eina_convert_atod(). - * - * The string must have the following format: - * - * @code - * [-]0xh.hhhhhp[+-]e - * @endcode - * - * where the h are the hexadecimal cyphers of the mantiss and e the - * exponent (a decimal number). If n is the number of cypers after the - * point, the returned mantiss and exponents are: - * - * @code - * mantiss : [-]hhhhhh - * exponent : 2^([+-]e - 4 * n) - * @endcode - * - * The mantiss and exponent are stored in the buffers pointed - * respectively by @p m and @p e. - * - * If the string is invalid, the error is set to: - * - * @li #EINA_ERROR_CONVERT_0X_NOT_FOUND if no 0x is found, - * @li #EINA_ERROR_CONVERT_P_NOT_FOUND if no p is found, - * @li #EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH if @p length is not - * correct. - * - * In those cases, or if @p fp is @c NULL, #EINA_FALSE is returned, - * otherwise @p fp is computed and #EINA_TRUE is returned. - * - * @note The code uses eina_convert_atod() and do the correct bit - * shift to compute the fixed point number. - */ -EAPI Eina_Bool -eina_convert_atofp(const char *src, int length, Eina_F32p32 * fp) -{ - long long m; - long e; - - if (!eina_convert_atod(src, length, &m, &e)) - return EINA_FALSE; - - if (!fp) - return EINA_TRUE; - - e += 32; - - if (e > 0) - *fp = m << e; - else - *fp = m >> -e; - - return EINA_TRUE; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_counter.c b/tests/suite/ecore/src/lib/eina_counter.c deleted file mode 100644 index 6b0c5b67a9..0000000000 --- a/tests/suite/ecore/src/lib/eina_counter.c +++ /dev/null @@ -1,491 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008 Cedric Bail, Vincent Torri - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#ifndef _WIN32 -#include <time.h> -#else -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#endif /* _WIN2 */ - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_inlist.h" -#include "eina_error.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_counter.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -#ifndef _WIN32 -typedef struct timespec Eina_Nano_Time; -#else -typedef LARGE_INTEGER Eina_Nano_Time; -#endif - -typedef struct _Eina_Clock Eina_Clock; - -struct _Eina_Counter { - EINA_INLIST; - - Eina_Inlist *clocks; - const char *name; -}; - -struct _Eina_Clock { - EINA_INLIST; - - Eina_Nano_Time start; - Eina_Nano_Time end; - int specimen; - - Eina_Bool valid; -}; - -#ifndef _WIN32 -static inline int _eina_counter_time_get(Eina_Nano_Time * tp) -{ -#if defined(CLOCK_PROCESS_CPUTIME_ID) - return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, tp); -#elif defined(CLOCK_PROF) - return clock_gettime(CLOCK_PROF, tp); -#elif defined(CLOCK_REALTIME) - return clock_gettime(CLOCK_REALTIME, tp); -#else - return gettimeofday(tp, NULL); -#endif -} -#else -static const char EINA_ERROR_COUNTER_WINDOWS_STR[] = - "Change your OS, you moron !"; -static int EINA_ERROR_COUNTER_WINDOWS = 0; -static LARGE_INTEGER _eina_counter_frequency; - -static inline int _eina_counter_time_get(Eina_Nano_Time * tp) -{ - return QueryPerformanceCounter(tp); -} -#endif /* _WIN2 */ - -static char *_eina_counter_asiprintf(char *base, int *position, - const char *format, ...) -{ - char *tmp, *result; - int size = 32; - int n; - va_list ap; - - tmp = realloc(base, sizeof(char) * (*position + size)); - if (!tmp) - return base; - - result = tmp; - - while (1) { - va_start(ap, format); - n = vsnprintf(result + *position, size, format, ap); - va_end(ap); - - if (n > -1 && n < size) { - /* If we always have glibc > 2.2, we could just return *position += n. */ - *position += strlen(result + *position); - return result; - } - - if (n > -1) - size = n + 1; - else - size <<= 1; - - tmp = realloc(result, sizeof(char) * (*position + size)); - if (!tmp) - return result; - - result = tmp; - } -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the eina counter internal structure. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the counter module set up by - * eina_counter_init(). It is called by eina_init(). - * - * This function sets up the error module of Eina and only on Windows, - * it initializes the high precision timer. It also registers, only on - * Windows, the error #EINA_ERROR_COUNTER_WINDOWS. It is also called - * by eina_init(). It returns 0 on failure, otherwise it returns the - * number of times it has already been called. - * - * @see eina_init() - */ -Eina_Bool eina_counter_init(void) -{ -#ifdef _WIN32 - EINA_ERROR_COUNTER_WINDOWS = - eina_error_msg_static_register(EINA_ERROR_COUNTER_WINDOWS_STR); - if (!QueryPerformanceFrequency(&_eina_counter_frequency)) { - eina_error_set(EINA_ERROR_COUNTER_WINDOWS); - return EINA_FALSE; - } -#endif /* _WIN2 */ - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the counter module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the counter module set up by - * eina_counter_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_counter_shutdown(void) -{ - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Counter_Group Counter - * - * @brief These functions allow you to get the time spent in a part of a code. - * - * Before using the counter system, Eina must be initialized with - * eina_init() and later shut down with eina_shutdown(). The create a - * counter, use eina_counter_new(). To free it, use - * eina_counter_free(). - * - * To time a part of a code, call eina_counter_start() just before it, - * and eina_counter_stop() just after it. Each time you start to time - * a code, a clock is added to a list. You can give a number of that - * clock with the second argument of eina_counter_stop(). To send all - * the registered clocks to a stream (like stdout, ofr a file), use - * eina_counter_dump(). - * - * Here is a straightforward example: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * - * #include <eina_counter.h> - * - * void test_malloc(void) - * { - * int i; - * - * for (i = 0; i < 100000; ++i) - * { - * void *buf; - * - * buf = malloc(100); - * free(buf); - * } - * } - * - * int main(void) - * { - * Eina_Counter *counter; - * - * if (!eina_init()) - * { - * printf("Error during the initialization of eina\n"); - * return EXIT_FAILURE; - * } - * - * counter = eina_counter_new("malloc"); - * - * eina_counter_start(counter); - * test_malloc(); - * eina_counter_stop(counter, 1); - * - * char* result = eina_counter_dump(counter); - * printf("%s", result); - * free(result); - * - * eina_counter_free(counter); - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - * Compile this code with the following commant: - * - * @verbatim - * gcc -Wall -o test_eina_counter test_eina.c `pkg-config --cflags --libs eina` - * @endverbatim - * - * The result should be something like that: - * - * @verbatim - * \# specimen experiment time starting time ending time - * 1 9794125 783816 10577941 - * @endverbatim - * - * Note that the displayed time is in nanosecond. - * - * @{ - */ - -/** - * @brief Return a counter. - * - * @param name The name of the counter. - * - * This function returns a new counter. It is characterized by @p - * name. If @p name is @c NULL, the function returns @c NULL - * immediately. If memory allocation fails, @c NULL is returned and the - * error is set to #EINA_ERROR_OUT_OF_MEMORY. - * - * Whe the new counter is not needed anymore, use eina_counter_free() to - * free the allocated memory. - */ -EAPI Eina_Counter *eina_counter_new(const char *name) -{ - Eina_Counter *counter; - size_t length; - - EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); - - length = strlen(name) + 1; - - eina_error_set(0); - counter = calloc(1, sizeof(Eina_Counter) + length); - if (!counter) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - counter->name = (char *) (counter + 1); - memcpy((char *) counter->name, name, length); - - return counter; -} - -/** - * @brief Delete a counter. - * - * @param counter The counter to delete. - * - * This function remove the clock of @p counter from the used clocks - * (see eina_counter_start()) and frees the memory allocated for - * @p counter. If @p counter is @c NULL, the function returns - * immediately. - */ -EAPI void eina_counter_free(Eina_Counter * counter) -{ - EINA_SAFETY_ON_NULL_RETURN(counter); - - while (counter->clocks) { - Eina_Clock *clk = (Eina_Clock *) counter->clocks; - - counter->clocks = - eina_inlist_remove(counter->clocks, counter->clocks); - free(clk); - } - - free(counter); -} - -/** - * @brief Start the time count. - * - * @param counter The counter. - * - * This function specifies that the part of the code beginning just - * after its call is being to be timed, using @p counter. If - * @p counter is @c NULL, this function returns immediately. - * - * This function adds the clock associated to @p counter in a list. If - * the memory needed by that clock can not be allocated, the function - * returns and the error is set to #EINA_ERROR_OUT_OF_MEMORY. - * - * To stop the timing, eina_counter_stop() must be called with the - * same counter. - */ -EAPI void eina_counter_start(Eina_Counter * counter) -{ - Eina_Clock *clk; - Eina_Nano_Time tp; - - EINA_SAFETY_ON_NULL_RETURN(counter); - if (_eina_counter_time_get(&tp) != 0) - return; - - eina_error_set(0); - clk = calloc(1, sizeof(Eina_Clock)); - if (!clk) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return; - } - - counter->clocks = - eina_inlist_prepend(counter->clocks, EINA_INLIST_GET(clk)); - - clk->valid = EINA_FALSE; - clk->start = tp; -} - -/** - * @brief Stop the time count. - * - * @param counter The counter. - * @param specimen The number of the test. - * - * This function stop the timing that has been started with - * eina_counter_start(). @p counter must be the same than the one used - * with eina_counter_start(). @p specimen is the number of the - * test. If @p counter or its associated clock are @c NULL, or if the - * time can't be retrieved the function exits. - */ -EAPI void eina_counter_stop(Eina_Counter * counter, int specimen) -{ - Eina_Clock *clk; - Eina_Nano_Time tp; - - EINA_SAFETY_ON_NULL_RETURN(counter); - if (_eina_counter_time_get(&tp) != 0) - return; - - clk = (Eina_Clock *) counter->clocks; - - if (!clk || clk->valid == EINA_TRUE) - return; - - clk->end = tp; - clk->specimen = specimen; - clk->valid = EINA_TRUE; -} - -/** - * @brief Dump the result of all clocks of a counter to a stream. - * - * @return A string with a summary of the test. - * @param counter The counter. - * - * This function returns an malloc'd string containing the dump of - * all the valid clocks of @p counter. - * If @p counter @c NULL, the functions exits - * immediately. Otherwise, the output is formattted like that: - * - * @verbatim - * \# specimen experiment time starting time ending time - * 1 208 120000 120208 - * @endverbatim - * - * The unit of time is the nanosecond. - */ -EAPI char *eina_counter_dump(Eina_Counter * counter) -{ - Eina_Clock *clk; - char *result = NULL; - int position = 0; - - EINA_SAFETY_ON_NULL_RETURN_VAL(counter, NULL); - - result = _eina_counter_asiprintf(result, - &position, - "# specimen\texperiment time\tstarting time\tending time\n"); - if (!result) - return NULL; - - EINA_INLIST_REVERSE_FOREACH(counter->clocks, clk) { - long int start; - long int end; - long int diff; - - if (clk->valid == EINA_FALSE) - continue; - -#ifndef _WIN32 - start = - clk->start.tv_sec * 1000000000 + clk->start.tv_nsec; - end = clk->end.tv_sec * 1000000000 + clk->end.tv_nsec; - diff = - (clk->end.tv_sec - - clk->start.tv_sec) * 1000000000 + clk->end.tv_nsec - - clk->start.tv_nsec; -#else - start = - (long int) (((long long int) clk->start.QuadPart * - 1000000000ll) / - (long long int) _eina_counter_frequency. - QuadPart); - end = - (long - int) (((long long int) clk->end.QuadPart * - 1000000000LL) / - (long long int) _eina_counter_frequency. - QuadPart); - diff = - (long - int) (((long long int) (clk->end.QuadPart - - clk->start.QuadPart) * - 1000000000LL) / - (long long int) _eina_counter_frequency. - QuadPart); -#endif /* _WIN2 */ - - result = _eina_counter_asiprintf(result, &position, - "%i\t%li\t%li\t%li\n", - clk->specimen, - diff, start, end); - } - - return result; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_cpu.c b/tests/suite/ecore/src/lib/eina_cpu.c deleted file mode 100644 index 1b839fc48e..0000000000 --- a/tests/suite/ecore/src/lib/eina_cpu.c +++ /dev/null @@ -1,151 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef EFL_HAVE_THREADS -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#elif defined (__SUNPRO_C) || defined(__GNUC__) -#include <unistd.h> -#elif defined (__FreeBSD__) || defined (__OpenBSD__) || \ - defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \ - (defined (__MACH__) && defined (__APPLE__)) -#include <unistd.h> -#include <sys/param.h> -#include <sys/sysctl.h> -#elif defined (__linux__) || defined(__GLIBC__) -#define _GNU_SOURCE -#include <sched.h> -#endif -#ifdef EFL_HAVE_POSIX_THREADS -#include <pthread.h> -#endif - -#define TH_MAX 8 -#endif - -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "eina_cpu.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/* FIXME this ifdefs should be replaced */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/* FIXME the features checks should be called when this function is called? - * or make it static by doing eina_cpu_init() and return a local var - */ -/** - * - * @return - */ -EAPI Eina_Cpu_Features eina_cpu_features_get(void) -{ - Eina_Cpu_Features ecf = 0; - return ecf; -} - -EAPI int eina_cpu_count(void) -{ -#ifdef EFL_HAVE_THREADS - -#if defined (_WIN32) - SYSTEM_INFO sysinfo; - - GetSystemInfo(&sysinfo); - return sysinfo.dwNumberOfProcessors; - -#elif defined (__SUNPRO_C) || defined(__GNUC__) - /* - * _SC_NPROCESSORS_ONLN: number of processors that are online, that - is available when sysconf is called. The number - of cpu can change by admins. - * _SC_NPROCESSORS_CONF: maximum number of processors that are available - to the current OS instance. That number can be - change after a reboot. - * _SC_NPROCESSORS_MAX : maximum number of processors that are on the - motherboard. - */ - return sysconf(_SC_NPROCESSORS_ONLN); - -#elif defined (__FreeBSD__) || defined (__OpenBSD__) || \ - defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \ - (defined (__MACH__) && defined (__APPLE__)) - - int mib[4]; - int cpus; - size_t len = sizeof(cpus); - - mib[0] = CTL_HW; -#ifdef HW_AVAILCPU - mib[1] = HW_AVAILCPU; -#else - mib[1] = HW_NCPU; -#endif - sysctl(mib, 2, &cpus, &len, NULL, 0); - if (cpus < 1) - cpus = 1; - - return cpus; - -#elif defined (__linux__) || defined(__GLIBC__) - cpu_set_t cpu; - int i; - static int cpus = 0; - - if (cpus != 0) - return cpus; - - CPU_ZERO(&cpu); - if (sched_getaffinity(0, sizeof(cpu), &cpu) != 0) { - fprintf(stderr, "[Eina] could not get cpu affinity: %s\n", - strerror(errno)); - return 1; - } - - for (i = 0; i < TH_MAX; i++) { - if (CPU_ISSET(i, &cpu)) - cpus = i + 1; - else - break; - } - return cpus; - -#else -#error "eina_cpu_count() error: Platform not supported" -#endif -#else - return 1; -#endif -} diff --git a/tests/suite/ecore/src/lib/eina_error.c b/tests/suite/ecore/src/lib/eina_error.c deleted file mode 100644 index 9bdf1c19e5..0000000000 --- a/tests/suite/ecore/src/lib/eina_error.c +++ /dev/null @@ -1,452 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - */ - - -/** - * @page tutorial_error_page Error Tutorial - * - * @section tutorial_error_introduction Introduction - * - * The Eina error module provides a way to manage errors in a simple - * but powerful way in libraries and modules. It is also used in Eina - * itself. Similar to libC's @c errno and strerror() facilities, this - * is extensible and recommended for other libraries and applications. - * - * @section tutorial_error_registering_msg Registering messages - * - * The error module can provide a system that mimic the errno system - * of the C standard library. It consists in 2 parts: - * - * @li a way of registering new messages with - * eina_error_msg_register() and eina_error_msg_get(), - * @li a way of setting / getting last error message with - * eina_error_set() / eina_error_get(). - * - * So one has to fisrt register all the error messages that a program - * or a lib should manage. Then, when an error can occur, use - * eina_error_set(), and when errors are managed, use - * eina_error_get(). If eina_error_set() is used to set an error, do - * not forget to call before eina_error_set0), to remove previous set - * errors. - * - * Here is an example of use: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * - * #include <eina_error.h> - * - * Eina_Error MY_ERROR_NEGATIVE; - * Eina_Error MY_ERROR_NULL; - * - * voi *data_new() - * { - * eina_error_set(0); - * - * eina_error_set(MY_ERROR_NULL); - * return NULL; - * } - * - * int test(int n) - * { - * eina_error_set(0); - * - * if (n < 0) - * { - * eina_error_set(MY_ERROR_NEGATIVE); - * return 0; - * } - * - * return 1; - * } - * - * int main(void) - * { - * void *data; - * - * if (!eina_init()) - * { - * printf ("Error during the initialization of eina_error module\n"); - * return EXIT_FAILURE; - * } - * - * MY_ERROR_NEGATIVE = eina_error_msg_register("Negative number"); - * MY_ERROR_NULL = eina_error_msg_register("NULL pointer"); - - * data = data_new(); - * if (!data) - * { - * Eina_Error err; - * - * err = eina_error_get(); - * if (err) - * printf("Error during memory allocation: %s\n", - * eina_error_msg_get(err)); - * } - * - * if (!test(0)) - * { - * Eina_Error err; - * - * err = eina_error_get(); - * if (err) - * printf("Error during test function: %s\n", - * eina_error_msg_get(err)); - * } - * - * if (!test(-1)) - * { - * Eina_Error err; - * - * err = eina_error_get(); - * if (err) - * printf("Error during test function: %s\n", - * eina_error_msg_get(err)); - * } - * - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - * Of course, instead of printf(), eina_log_print() can be used to - * have beautiful error messages. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" - - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_error.h" - -/* TODO - * + add a wrapper for assert? - * + add common error numbers, messages - * + add a calltrace of errors, not only store the last error but a list of them - * and also store the function that set it - */ - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -typedef struct _Eina_Error_Message Eina_Error_Message; -struct _Eina_Error_Message { - Eina_Bool string_allocated; - const char *string; -}; - -static Eina_Error_Message *_eina_errors = NULL; -static size_t _eina_errors_count = 0; -static size_t _eina_errors_allocated = 0; -static Eina_Error _eina_last_error; - -static Eina_Error_Message *_eina_error_msg_alloc(void) -{ - size_t idx; - - if (_eina_errors_count == _eina_errors_allocated) { - void *tmp; - size_t size; - - if (EINA_UNLIKELY(_eina_errors_allocated == 0)) - size = 24; - else - size = _eina_errors_allocated + 8; - - tmp = - realloc(_eina_errors, - sizeof(Eina_Error_Message) * size); - if (!tmp) - return NULL; - - _eina_errors = tmp; - _eina_errors_allocated = size; - } - - idx = _eina_errors_count; - _eina_errors_count++; - return _eina_errors + idx; -} - -/** - * @endcond - */ - - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = 0; - -static const char EINA_ERROR_OUT_OF_MEMORY_STR[] = "Out of memory"; - -/** - * @endcond - */ - -/** - * @internal - * @brief Initialize the error module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the error module of Eina. It is called by - * eina_init(). - * - * This function registers the error #EINA_ERROR_OUT_OF_MEMORY. - * - * @see eina_init() - */ -Eina_Bool eina_error_init(void) -{ - /* TODO register the eina's basic errors */ - EINA_ERROR_OUT_OF_MEMORY = - eina_error_msg_static_register(EINA_ERROR_OUT_OF_MEMORY_STR); - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the error module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the error module set up by - * eina_error_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_error_shutdown(void) -{ - Eina_Error_Message *eem, *eem_end; - - eem = _eina_errors; - eem_end = eem + _eina_errors_count; - - for (; eem < eem_end; eem++) - if (eem->string_allocated) - free((char *) eem->string); - - free(_eina_errors); - _eina_errors = NULL; - _eina_errors_count = 0; - _eina_errors_allocated = 0; - - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Error_Group Error - * - * @brief These functions provide error management for projects. - * - * To use the error system Eina must be initialized with eina_init() - * and later shut down with eina_shutdown(). Error codes are - * registered with eina_error_msg_register() and converted from - * identifier to original message string with eina_error_msg_get(). - * - * Logging functions are not in eina_error anymore, see - * eina_log_print() instead. - * - * @{ - */ - -/** - * @brief Register a new error type. - * - * @param msg The description of the error. It will be duplicated using - * strdup(). - * @return The unique number identifier for this error. - * - * This function stores in a list the error message described by - * @p msg. The returned value is a unique identifier greater or equal - * than 1. The description can be retrieve later by passing to - * eina_error_msg_get() the returned value. - * - * @see eina_error_msg_static_register() - */ -EAPI Eina_Error eina_error_msg_register(const char *msg) -{ - Eina_Error_Message *eem; - - EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0); - - eem = _eina_error_msg_alloc(); - if (!eem) - return 0; - - eem->string_allocated = EINA_TRUE; - eem->string = strdup(msg); - if (!eem->string) { - _eina_errors_count--; - return 0; - } - - return _eina_errors_count; /* identifier = index + 1 (== _count). */ -} - -/** - * @brief Register a new error type, statically allocated message. - * - * @param msg The description of the error. This string will not be - * duplicated and thus the given pointer should live during - * usage of eina_error. - * @return The unique number identifier for this error. - * - * This function stores in a list the error message described by - * @p msg. The returned value is a unique identifier greater or equal - * than 1. The description can be retrieve later by passing to - * eina_error_msg_get() the returned value. - * - * @see eina_error_msg_register() - */ -EAPI Eina_Error eina_error_msg_static_register(const char *msg) -{ - Eina_Error_Message *eem; - - EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0); - - eem = _eina_error_msg_alloc(); - if (!eem) - return 0; - - eem->string_allocated = EINA_FALSE; - eem->string = msg; - return _eina_errors_count; /* identifier = index + 1 (== _count). */ -} - -/** - * @brief Change the message of an already registered message - * - * @param error The Eina_Error to change the message of - * @param msg The description of the error. This string will be - * duplicated only if the error was registered with @ref eina_error_msg_register - * otherwise it must remain intact for the duration - * @return EINA_TRUE if successful, EINA_FALSE on error - * - * This function modifies the message associated with @p error and changes - * it to @p msg. If the error was previously registered by @ref eina_error_msg_static_register - * then the string will not be duplicated, otherwise the previous message - * will be freed and @p msg copied. - * - * @see eina_error_msg_register() - */ -EAPI Eina_Bool eina_error_msg_modify(Eina_Error error, const char *msg) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(msg, EINA_FALSE); - if (error < 1) - return EINA_FALSE; - - if ((size_t) error > _eina_errors_count) - return EINA_FALSE; - - if (_eina_errors[error - 1].string_allocated) { - const char *tmp; - - if (!(tmp = strdup(msg))) - return EINA_FALSE; - - free((void *) _eina_errors[error - 1].string); - _eina_errors[error - 1].string = tmp; - return EINA_TRUE; - } - - _eina_errors[error - 1].string = msg; - return EINA_TRUE; -} - -/** - * @brief Return the description of the given an error number. - * - * @param error The error number. - * @return The description of the error. - * - * This function returns the description of an error that has been - * registered with eina_error_msg_register(). If an incorrect error is - * given, then @c NULL is returned. - */ -EAPI const char *eina_error_msg_get(Eina_Error error) -{ - if (error < 1) - return NULL; - - if ((size_t) error > _eina_errors_count) - return NULL; - - return _eina_errors[error - 1].string; -} - -/** - * @brief Return the last set error. - * - * @return The last error. - * - * This function returns the last error set by eina_error_set(). The - * description of the message is returned by eina_error_msg_get(). - */ -EAPI Eina_Error eina_error_get(void) -{ - return _eina_last_error; -} - -/** - * @brief Set the last error. - * - * @param err The error identifier. - * - * This function sets the last error identifier. The last error can be - * retrieved with eina_error_get(). - */ -EAPI void eina_error_set(Eina_Error err) -{ - _eina_last_error = err; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_file.c b/tests/suite/ecore/src/lib/eina_file.c deleted file mode 100644 index 454d0ca729..0000000000 --- a/tests/suite/ecore/src/lib/eina_file.c +++ /dev/null @@ -1,533 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Vincent Torri - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef _WIN32 -#define _GNU_SOURCE -#endif - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#elif defined __GNUC__ -#define alloca __builtin_alloca -#elif defined _AIX -#define alloca __alloca -#elif defined _MSC_VER -#include <malloc.h> -#define alloca _alloca -#else -#include <stddef.h> -#ifdef __cplusplus -extern "C" -#endif -void *alloca(size_t); -#endif - -#include <string.h> -#include <dirent.h> - -#ifndef _WIN32 -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#else -#include <Evil.h> -#endif /* _WIN2 */ - -#ifndef _WIN32 -#define PATH_DELIM '/' -#else -#define PATH_DELIM '\\' -#define NAME_MAX MAX_PATH -#endif - -#ifdef __sun -#ifndef NAME_MAX -#define NAME_MAX 255 -#endif -#endif - -#include "eina_config.h" -#include "eina_private.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_file.h" -#include "eina_stringshare.h" - -typedef struct _Eina_File_Iterator Eina_File_Iterator; -struct _Eina_File_Iterator { - Eina_Iterator iterator; - - DIR *dirp; - int length; - - char dir[1]; -}; - -static Eina_Bool -_eina_file_ls_iterator_next(Eina_File_Iterator * it, void **data) -{ - struct dirent *dp; - char *name; - size_t length; - - do { - dp = readdir(it->dirp); - if (!dp) - return EINA_FALSE; - } - while ((dp->d_name[0] == '.') && - ((dp->d_name[1] == '\0') || - ((dp->d_name[1] == '.') && (dp->d_name[2] == '\0')))); - - length = strlen(dp->d_name); - name = alloca(length + 2 + it->length); - - memcpy(name, it->dir, it->length); - memcpy(name + it->length, "/", 1); - memcpy(name + it->length + 1, dp->d_name, length + 1); - - *data = (char *) eina_stringshare_add(name); - return EINA_TRUE; -} - -static char *_eina_file_ls_iterator_container(Eina_File_Iterator * it) -{ - return it->dir; -} - -static void _eina_file_ls_iterator_free(Eina_File_Iterator * it) -{ - closedir(it->dirp); - - EINA_MAGIC_SET(&it->iterator, 0); - free(it); -} - -typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; -struct _Eina_File_Direct_Iterator { - Eina_Iterator iterator; - - DIR *dirp; - int length; - - Eina_File_Direct_Info info; - - char dir[1]; -}; - -static Eina_Bool -_eina_file_direct_ls_iterator_next(Eina_File_Direct_Iterator * it, - void **data) -{ - struct dirent *dp; - size_t length; - - do { - dp = readdir(it->dirp); - if (!dp) - return EINA_FALSE; - - length = strlen(dp->d_name); - if (it->info.name_start + length + 1 >= PATH_MAX) - continue; - } - while ((dp->d_name[0] == '.') && - ((dp->d_name[1] == '\0') || - ((dp->d_name[1] == '.') && (dp->d_name[2] == '\0')))); - - memcpy(it->info.path + it->info.name_start, dp->d_name, length); - it->info.name_length = length; - it->info.path_length = it->info.name_start + length; - it->info.path[it->info.path_length] = '\0'; - it->info.dirent = dp; - - *data = &it->info; - return EINA_TRUE; -} - -static char - *_eina_file_direct_ls_iterator_container(Eina_File_Direct_Iterator * - it) -{ - return it->dir; -} - -static void -_eina_file_direct_ls_iterator_free(Eina_File_Direct_Iterator * it) -{ - closedir(it->dirp); - - EINA_MAGIC_SET(&it->iterator, 0); - free(it); -} - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_File_Group File - * - * @brief Functions to traverse directories and split paths. - * - * @li eina_file_dir_list() list the content of a directory, - * recusrsively or not, and can call a callback function for eachfound - * file. - * @li eina_file_split() split a path into all the subdirectories that - * compose it, according to the separator of the file system. - * - * @{ - */ - -/** - * @brief List all files on the directory calling the function for every file found. - * - * @param dir The directory name. - * @param recursive Iterate recursively in the directory. - * @param cb The callback to be called. - * @param data The data to pass to the callback. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function lists all the files in @p dir. To list also all the - * sub directoris recursively, @p recursive must be set to #EINA_TRUE, - * otherwise it must be set to #EINA_FALSE. For each found file, @p cb - * is called and @p data is passed to it. - * - * If @p cb or @p dir are @c NULL, or if @p dir is a string of size 0, - * or if @p dir can not be opened, this function returns #EINA_FALSE - * immediately. otherwise, it returns #EINA_TRUE. - */ -EAPI Eina_Bool -eina_file_dir_list(const char *dir, - Eina_Bool recursive, - Eina_File_Dir_List_Cb cb, void *data) -{ -#ifndef _WIN32 - struct dirent *de; - DIR *d; - - EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE); - EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE); - - d = opendir(dir); - if (!d) - return EINA_FALSE; - - while ((de = readdir(d))) { - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) - continue; - - cb(de->d_name, dir, data); - /* d_type is only available on linux and bsd (_BSD_SOURCE) */ - - if (recursive == EINA_TRUE) { - char *path; - - path = - alloca(strlen(dir) + strlen(de->d_name) + 2); - strcpy(path, dir); - strcat(path, "/"); - strcat(path, de->d_name); -#ifndef sun - if (de->d_type == DT_UNKNOWN) { -#endif - struct stat st; - - if (stat(path, &st)) - continue; - - if (!S_ISDIR(st.st_mode)) - continue; - -#ifndef sun - } else if (de->d_type != DT_DIR) - continue; - -#endif - - eina_file_dir_list(path, recursive, cb, data); - } - } - - closedir(d); -#else - WIN32_FIND_DATA file; - HANDLE hSearch; - char *new_dir; - TCHAR *tdir; - size_t length_dir; - - EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE); - EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE); - - length_dir = strlen(dir); - new_dir = (char *) alloca(length_dir + 5); - if (!new_dir) - return EINA_FALSE; - - memcpy(new_dir, dir, length_dir); - memcpy(new_dir + length_dir, "/*.*", 5); - -#ifdef UNICODE - tdir = evil_char_to_wchar(new_dir); -#else - tdir = new_dir; -#endif /* ! UNICODE */ - hSearch = FindFirstFile(tdir, &file); -#ifdef UNICODE - free(tdir); -#endif /* UNICODE */ - - if (hSearch == INVALID_HANDLE_VALUE) - return EINA_FALSE; - - do { - char *filename; - -#ifdef UNICODE - filename = evil_wchar_to_char(file.cFileName); -#else - filename = file.cFileName; -#endif /* ! UNICODE */ - if (!strcmp(filename, ".") || !strcmp(filename, "..")) - continue; - - cb(filename, dir, data); - - if (recursive == EINA_TRUE) { - char *path; - - path = alloca(strlen(dir) + strlen(filename) + 2); - strcpy(path, dir); - strcat(path, "/"); - strcat(path, filename); - - if (! - (file. - dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - continue; - - eina_file_dir_list(path, recursive, cb, data); - } -#ifdef UNICODE - free(filename); -#endif /* UNICODE */ - - } while (FindNextFile(hSearch, &file)); - FindClose(hSearch); -#endif /* _WIN32 */ - - return EINA_TRUE; -} - -/** - * @brief Split a path according to the delimiter of the filesystem. - * - * @param path The path to split. - * @return An array of the parts of the path to split. - * - * This function splits @p path according to the delimiter of the used - * filesystem. If @p path is @c NULL or if the array can not be - * created, @c NULL is returned, otherwise, an array with the - * different parts of @p path is returned. - */ -EAPI Eina_Array *eina_file_split(char *path) -{ - Eina_Array *ea; - char *current; - size_t length; - - EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); - - ea = eina_array_new(16); - - if (!ea) - return NULL; - - for (current = strchr(path, PATH_DELIM); - current; - path = current + 1, current = strchr(path, PATH_DELIM)) { - length = current - path; - - if (length <= 0) - continue; - - eina_array_push(ea, path); - *current = '\0'; - } - - if (*path != '\0') - eina_array_push(ea, path); - - return ea; -} - -/** - * Get an iterator to list the content of a directory. - * - * Iterators are cheap to be created and allow interruption at any - * iteration. At each iteration, only the next directory entry is read - * from the filesystem with readdir(). - * - * The iterator will handle the user a stringshared value with the - * full path. One must call eina_stringshare_del() on it after usage - * to not leak! - * - * The eina_file_direct_ls() function will provide a possibly faster - * alternative if you need to filter the results somehow, like - * checking extension. - * - * The iterator will walk over '.' and '..' without returning them. - * - * @param dir The name of the directory to list - * @return Return an Eina_Iterator that will walk over the files and - * directory in the pointed directory. On failure it will - * return NULL. The iterator emits stringshared value with the - * full path and must be freed with eina_stringshare_del(). - * - * @see eina_file_direct_ls() - */ -EAPI Eina_Iterator *eina_file_ls(const char *dir) -{ - Eina_File_Iterator *it; - size_t length; - - if (!dir) - return NULL; - - length = strlen(dir); - if (length < 1) - return NULL; - - it = calloc(1, sizeof(Eina_File_Iterator) + length); - if (!it) - return NULL; - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->dirp = opendir(dir); - if (!it->dirp) { - free(it); - return NULL; - } - - memcpy(it->dir, dir, length + 1); - if (dir[length - 1] != '/') - it->length = length; - else - it->length = length - 1; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = - FUNC_ITERATOR_NEXT(_eina_file_ls_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(_eina_file_ls_iterator_container); - it->iterator.free = - FUNC_ITERATOR_FREE(_eina_file_ls_iterator_free); - - return &it->iterator; -} - -/** - * Get an iterator to list the content of a directory, with direct information. - * - * Iterators are cheap to be created and allow interruption at any - * iteration. At each iteration, only the next directory entry is read - * from the filesystem with readdir(). - * - * The iterator returns the direct pointer to couple of useful information in - * #Eina_File_Direct_Info and that pointer should not be modified anyhow! - * - * The iterator will walk over '.' and '..' without returning them. - * - * @param dir The name of the directory to list - - * @return Return an Eina_Iterator that will walk over the files and - * directory in the pointed directory. On failure it will - * return NULL. The iterator emits #Eina_File_Direct_Info - * pointers that could be used but not modified. The lifetime - * of the returned pointer is until the next iteration and - * while the iterator is live, deleting the iterator - * invalidates the pointer. - * - * @see eina_file_ls() - */ -EAPI Eina_Iterator *eina_file_direct_ls(const char *dir) -{ - Eina_File_Direct_Iterator *it; - size_t length; - - if (!dir) - return NULL; - - length = strlen(dir); - if (length < 1) - return NULL; - - if (length + NAME_MAX + 2 >= PATH_MAX) - return NULL; - - it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length); - if (!it) - return NULL; - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->dirp = opendir(dir); - if (!it->dirp) { - free(it); - return NULL; - } - - memcpy(it->dir, dir, length + 1); - it->length = length; - - memcpy(it->info.path, dir, length); - if (dir[length - 1] == '/') - it->info.name_start = length; - else { - it->info.path[length] = '/'; - it->info.name_start = length + 1; - } - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = - FUNC_ITERATOR_NEXT(_eina_file_direct_ls_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER - (_eina_file_direct_ls_iterator_container); - it->iterator.free = - FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free); - - return &it->iterator; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_fp.c b/tests/suite/ecore/src/lib/eina_fp.c deleted file mode 100644 index 890c58ca88..0000000000 --- a/tests/suite/ecore/src/lib/eina_fp.c +++ /dev/null @@ -1,538 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <math.h> - -#include "eina_types.h" -#include "eina_fp.h" - -#define MAX_PREC 1025 -static const Eina_F32p32 eina_trigo[MAX_PREC] = { - 0x0000000100000000, 0x00000000ffffec43, 0x00000000ffffb10b, - 0x00000000ffff4e5a, 0x00000000fffec42e, 0x00000000fffe1287, - 0x00000000fffd3967, 0x00000000fffc38cd, 0x00000000fffb10b9, - 0x00000000fff9c12c, - 0x00000000fff84a25, 0x00000000fff6aba5, 0x00000000fff4e5ac, - 0x00000000fff2f83b, 0x00000000fff0e351, 0x00000000ffeea6ef, - 0x00000000ffec4316, 0x00000000ffe9b7c5, 0x00000000ffe704fe, - 0x00000000ffe42ac0, - 0x00000000ffe1290b, 0x00000000ffddffe2, 0x00000000ffdaaf43, - 0x00000000ffd7372f, 0x00000000ffd397a8, 0x00000000ffcfd0ad, - 0x00000000ffcbe23f, 0x00000000ffc7cc5f, 0x00000000ffc38f0d, - 0x00000000ffbf2a4b, - 0x00000000ffba9e17, 0x00000000ffb5ea75, 0x00000000ffb10f63, - 0x00000000ffac0ce3, 0x00000000ffa6e2f6, 0x00000000ffa1919c, - 0x00000000ff9c18d6, 0x00000000ff9678a6, 0x00000000ff90b10b, - 0x00000000ff8ac208, - 0x00000000ff84ab9c, 0x00000000ff7e6dc8, 0x00000000ff78088f, - 0x00000000ff717bf0, 0x00000000ff6ac7ec, 0x00000000ff63ec85, - 0x00000000ff5ce9bc, 0x00000000ff55bf92, 0x00000000ff4e6e08, - 0x00000000ff46f51f, - 0x00000000ff3f54d8, 0x00000000ff378d34, 0x00000000ff2f9e35, - 0x00000000ff2787dc, 0x00000000ff1f4a2a, 0x00000000ff16e520, - 0x00000000ff0e58c0, 0x00000000ff05a50a, 0x00000000fefcca01, - 0x00000000fef3c7a6, - 0x00000000feea9df9, 0x00000000fee14cfe, 0x00000000fed7d4b3, - 0x00000000fece351d, 0x00000000fec46e3b, 0x00000000feba800f, - 0x00000000feb06a9c, 0x00000000fea62de1, 0x00000000fe9bc9e2, - 0x00000000fe913e9f, - 0x00000000fe868c1b, 0x00000000fe7bb256, 0x00000000fe70b153, - 0x00000000fe658913, 0x00000000fe5a3998, 0x00000000fe4ec2e4, - 0x00000000fe4324f9, 0x00000000fe375fd7, 0x00000000fe2b7382, - 0x00000000fe1f5ffa, - 0x00000000fe132543, 0x00000000fe06c35d, 0x00000000fdfa3a4b, - 0x00000000fded8a0e, 0x00000000fde0b2a8, 0x00000000fdd3b41c, - 0x00000000fdc68e6c, 0x00000000fdb94199, 0x00000000fdabcda5, - 0x00000000fd9e3294, - 0x00000000fd907065, 0x00000000fd82871d, 0x00000000fd7476bd, - 0x00000000fd663f46, 0x00000000fd57e0bd, 0x00000000fd495b21, - 0x00000000fd3aae77, 0x00000000fd2bdabf, 0x00000000fd1cdffd, - 0x00000000fd0dbe32, - 0x00000000fcfe7562, 0x00000000fcef058e, 0x00000000fcdf6eb8, - 0x00000000fccfb0e4, 0x00000000fcbfcc13, 0x00000000fcafc048, - 0x00000000fc9f8d86, 0x00000000fc8f33ce, 0x00000000fc7eb325, - 0x00000000fc6e0b8b, - 0x00000000fc5d3d03, 0x00000000fc4c4791, 0x00000000fc3b2b37, - 0x00000000fc29e7f7, 0x00000000fc187dd5, 0x00000000fc06ecd2, - 0x00000000fbf534f2, 0x00000000fbe35637, 0x00000000fbd150a3, - 0x00000000fbbf243b, - 0x00000000fbacd100, 0x00000000fb9a56f6, 0x00000000fb87b61f, - 0x00000000fb74ee7e, 0x00000000fb620016, 0x00000000fb4eeaea, - 0x00000000fb3baefd, 0x00000000fb284c52, 0x00000000fb14c2eb, - 0x00000000fb0112cd, - 0x00000000faed3bf9, 0x00000000fad93e73, 0x00000000fac51a3f, - 0x00000000fab0cf5e, 0x00000000fa9c5dd5, 0x00000000fa87c5a6, - 0x00000000fa7306d5, 0x00000000fa5e2164, 0x00000000fa491558, - 0x00000000fa33e2b3, - 0x00000000fa1e8978, 0x00000000fa0909ab, 0x00000000f9f36350, - 0x00000000f9dd9668, 0x00000000f9c7a2f9, 0x00000000f9b18905, - 0x00000000f99b488f, 0x00000000f984e19c, 0x00000000f96e542e, - 0x00000000f957a049, - 0x00000000f940c5f1, 0x00000000f929c528, 0x00000000f9129df3, - 0x00000000f8fb5056, 0x00000000f8e3dc53, 0x00000000f8cc41ee, - 0x00000000f8b4812b, 0x00000000f89c9a0e, 0x00000000f8848c9b, - 0x00000000f86c58d4, - 0x00000000f853febe, 0x00000000f83b7e5d, 0x00000000f822d7b4, - 0x00000000f80a0ac7, 0x00000000f7f1179a, 0x00000000f7d7fe31, - 0x00000000f7bebe90, 0x00000000f7a558ba, 0x00000000f78bccb3, - 0x00000000f7721a80, - 0x00000000f7584225, 0x00000000f73e43a5, 0x00000000f7241f04, - 0x00000000f709d446, 0x00000000f6ef6370, 0x00000000f6d4cc85, - 0x00000000f6ba0f8a, 0x00000000f69f2c83, 0x00000000f6842374, - 0x00000000f668f461, - 0x00000000f64d9f4e, 0x00000000f632243f, 0x00000000f616833a, - 0x00000000f5fabc41, 0x00000000f5decf59, 0x00000000f5c2bc87, - 0x00000000f5a683cf, 0x00000000f58a2535, 0x00000000f56da0be, - 0x00000000f550f66e, - 0x00000000f5342649, 0x00000000f5173054, 0x00000000f4fa1494, - 0x00000000f4dcd30c, 0x00000000f4bf6bc2, 0x00000000f4a1deb9, - 0x00000000f4842bf7, 0x00000000f4665380, 0x00000000f4485559, - 0x00000000f42a3186, - 0x00000000f40be80c, 0x00000000f3ed78ef, 0x00000000f3cee434, - 0x00000000f3b029e1, 0x00000000f39149f9, 0x00000000f3724482, - 0x00000000f3531980, 0x00000000f333c8f8, 0x00000000f31452ef, - 0x00000000f2f4b76a, - 0x00000000f2d4f66d, 0x00000000f2b50ffe, 0x00000000f2950421, - 0x00000000f274d2dc, 0x00000000f2547c33, 0x00000000f234002b, - 0x00000000f2135eca, 0x00000000f1f29814, 0x00000000f1d1ac0e, - 0x00000000f1b09abe, - 0x00000000f18f6429, 0x00000000f16e0853, 0x00000000f14c8742, - 0x00000000f12ae0fb, 0x00000000f1091583, 0x00000000f0e724e0, - 0x00000000f0c50f17, 0x00000000f0a2d42c, 0x00000000f0807426, - 0x00000000f05def09, - 0x00000000f03b44db, 0x00000000f01875a1, 0x00000000eff58161, - 0x00000000efd2681f, 0x00000000efaf29e2, 0x00000000ef8bc6af, - 0x00000000ef683e8b, 0x00000000ef44917b, 0x00000000ef20bf86, - 0x00000000eefcc8b1, - 0x00000000eed8ad01, 0x00000000eeb46c7b, 0x00000000ee900727, - 0x00000000ee6b7d08, 0x00000000ee46ce25, 0x00000000ee21fa83, - 0x00000000edfd0228, 0x00000000edd7e51a, 0x00000000edb2a35f, - 0x00000000ed8d3cfc, - 0x00000000ed67b1f6, 0x00000000ed420255, 0x00000000ed1c2e1d, - 0x00000000ecf63554, 0x00000000ecd01801, 0x00000000eca9d628, - 0x00000000ec836fd1, 0x00000000ec5ce501, 0x00000000ec3635bd, - 0x00000000ec0f620d, - 0x00000000ebe869f5, 0x00000000ebc14d7d, 0x00000000eb9a0ca9, - 0x00000000eb72a780, 0x00000000eb4b1e08, 0x00000000eb237047, - 0x00000000eafb9e43, 0x00000000ead3a803, 0x00000000eaab8d8d, - 0x00000000ea834ee6, - 0x00000000ea5aec15, 0x00000000ea326520, 0x00000000ea09ba0d, - 0x00000000e9e0eae4, 0x00000000e9b7f7a9, 0x00000000e98ee063, - 0x00000000e965a51a, 0x00000000e93c45d2, 0x00000000e912c292, - 0x00000000e8e91b61, - 0x00000000e8bf5046, 0x00000000e8956146, 0x00000000e86b4e68, - 0x00000000e84117b3, 0x00000000e816bd2d, 0x00000000e7ec3edc, - 0x00000000e7c19cc8, 0x00000000e796d6f6, 0x00000000e76bed6e, - 0x00000000e740e036, - 0x00000000e715af54, 0x00000000e6ea5ad0, 0x00000000e6bee2af, - 0x00000000e69346f9, 0x00000000e66787b5, 0x00000000e63ba4e9, - 0x00000000e60f9e9b, 0x00000000e5e374d4, 0x00000000e5b72798, - 0x00000000e58ab6f1, - 0x00000000e55e22e3, 0x00000000e5316b76, 0x00000000e50490b1, - 0x00000000e4d7929c, 0x00000000e4aa713c, 0x00000000e47d2c98, - 0x00000000e44fc4b9, 0x00000000e42239a4, 0x00000000e3f48b61, - 0x00000000e3c6b9f7, - 0x00000000e398c56c, 0x00000000e36aadc9, 0x00000000e33c7314, - 0x00000000e30e1554, 0x00000000e2df9490, 0x00000000e2b0f0d0, - 0x00000000e2822a1a, 0x00000000e2534077, 0x00000000e22433ec, - 0x00000000e1f50482, - 0x00000000e1c5b240, 0x00000000e1963d2d, 0x00000000e166a550, - 0x00000000e136eab0, 0x00000000e1070d56, 0x00000000e0d70d48, - 0x00000000e0a6ea8e, 0x00000000e076a52f, 0x00000000e0463d33, - 0x00000000e015b2a1, - 0x00000000dfe50580, 0x00000000dfb435d9, 0x00000000df8343b2, - 0x00000000df522f13, 0x00000000df20f804, 0x00000000deef9e8d, - 0x00000000debe22b5, 0x00000000de8c8483, 0x00000000de5ac3ff, - 0x00000000de28e131, - 0x00000000ddf6dc21, 0x00000000ddc4b4d6, 0x00000000dd926b59, - 0x00000000dd5fffb0, 0x00000000dd2d71e3, 0x00000000dcfac1fb, - 0x00000000dcc7f000, 0x00000000dc94fbf8, 0x00000000dc61e5ec, - 0x00000000dc2eade4, - 0x00000000dbfb53e8, 0x00000000dbc7d7ff, 0x00000000db943a31, - 0x00000000db607a88, 0x00000000db2c9909, 0x00000000daf895bf, - 0x00000000dac470af, 0x00000000da9029e3, 0x00000000da5bc163, - 0x00000000da273737, - 0x00000000d9f28b66, 0x00000000d9bdbdf9, 0x00000000d988cef8, - 0x00000000d953be6b, 0x00000000d91e8c5b, 0x00000000d8e938d0, - 0x00000000d8b3c3d1, 0x00000000d87e2d67, 0x00000000d848759b, - 0x00000000d8129c74, - 0x00000000d7dca1fb, 0x00000000d7a68638, 0x00000000d7704934, - 0x00000000d739eaf7, 0x00000000d7036b89, 0x00000000d6cccaf3, - 0x00000000d696093d, 0x00000000d65f266f, 0x00000000d6282293, - 0x00000000d5f0fdb0, - 0x00000000d5b9b7d0, 0x00000000d58250fa, 0x00000000d54ac937, - 0x00000000d513208f, 0x00000000d4db570c, 0x00000000d4a36cb6, - 0x00000000d46b6195, 0x00000000d43335b3, 0x00000000d3fae917, - 0x00000000d3c27bcb, - 0x00000000d389edd7, 0x00000000d3513f43, 0x00000000d318701a, - 0x00000000d2df8063, 0x00000000d2a67027, 0x00000000d26d3f6f, - 0x00000000d233ee43, 0x00000000d1fa7cae, 0x00000000d1c0eab7, - 0x00000000d1873867, - 0x00000000d14d65c8, 0x00000000d11372e1, 0x00000000d0d95fbd, - 0x00000000d09f2c64, 0x00000000d064d8df, 0x00000000d02a6537, - 0x00000000cfefd176, 0x00000000cfb51da3, 0x00000000cf7a49c8, - 0x00000000cf3f55ef, - 0x00000000cf044220, 0x00000000cec90e64, 0x00000000ce8dbac5, - 0x00000000ce52474c, 0x00000000ce16b401, 0x00000000cddb00ef, - 0x00000000cd9f2e1e, 0x00000000cd633b97, 0x00000000cd272964, - 0x00000000cceaf78e, - 0x00000000ccaea61e, 0x00000000cc72351e, 0x00000000cc35a497, - 0x00000000cbf8f492, 0x00000000cbbc2519, 0x00000000cb7f3634, - 0x00000000cb4227ee, 0x00000000cb04fa50, 0x00000000cac7ad63, - 0x00000000ca8a4131, - 0x00000000ca4cb5c3, 0x00000000ca0f0b22, 0x00000000c9d14159, - 0x00000000c9935870, 0x00000000c9555072, 0x00000000c9172967, - 0x00000000c8d8e35a, 0x00000000c89a7e53, 0x00000000c85bfa5e, - 0x00000000c81d5782, - 0x00000000c7de95cb, 0x00000000c79fb541, 0x00000000c760b5ee, - 0x00000000c72197dc, 0x00000000c6e25b15, 0x00000000c6a2ffa3, - 0x00000000c663858f, 0x00000000c623ece2, 0x00000000c5e435a8, - 0x00000000c5a45fe9, - 0x00000000c5646bb0, 0x00000000c5245906, 0x00000000c4e427f6, - 0x00000000c4a3d888, 0x00000000c4636ac8, 0x00000000c422debf, - 0x00000000c3e23476, 0x00000000c3a16bf9, 0x00000000c3608550, - 0x00000000c31f8087, - 0x00000000c2de5da6, 0x00000000c29d1cb8, 0x00000000c25bbdc8, - 0x00000000c21a40de, 0x00000000c1d8a606, 0x00000000c196ed49, - 0x00000000c15516b2, 0x00000000c113224a, 0x00000000c0d1101d, - 0x00000000c08ee033, - 0x00000000c04c9297, 0x00000000c00a2754, 0x00000000bfc79e73, - 0x00000000bf84f800, 0x00000000bf423404, 0x00000000beff5289, - 0x00000000bebc539a, 0x00000000be793741, 0x00000000be35fd89, - 0x00000000bdf2a67b, - 0x00000000bdaf3223, 0x00000000bd6ba08b, 0x00000000bd27f1bc, - 0x00000000bce425c2, 0x00000000bca03ca7, 0x00000000bc5c3676, - 0x00000000bc181338, 0x00000000bbd3d2f9, 0x00000000bb8f75c3, - 0x00000000bb4afba1, - 0x00000000bb06649c, 0x00000000bac1b0c0, 0x00000000ba7ce018, - 0x00000000ba37f2ad, 0x00000000b9f2e88b, 0x00000000b9adc1bc, - 0x00000000b9687e4a, 0x00000000b9231e41, 0x00000000b8dda1ac, - 0x00000000b8980894, - 0x00000000b8525305, 0x00000000b80c8109, 0x00000000b7c692ac, - 0x00000000b78087f7, 0x00000000b73a60f6, 0x00000000b6f41db4, - 0x00000000b6adbe3a, 0x00000000b6674296, 0x00000000b620aad0, - 0x00000000b5d9f6f4, - 0x00000000b593270e, 0x00000000b54c3b27, 0x00000000b505334a, - 0x00000000b4be0f84, 0x00000000b476cfde, 0x00000000b42f7464, - 0x00000000b3e7fd20, 0x00000000b3a06a1e, 0x00000000b358bb69, - 0x00000000b310f10c, - 0x00000000b2c90b11, 0x00000000b2810985, 0x00000000b238ec71, - 0x00000000b1f0b3e2, 0x00000000b1a85fe2, 0x00000000b15ff07c, - 0x00000000b11765bc, 0x00000000b0cebfad, 0x00000000b085fe5a, - 0x00000000b03d21ce, - 0x00000000aff42a15, 0x00000000afab1739, 0x00000000af61e946, - 0x00000000af18a048, 0x00000000aecf3c49, 0x00000000ae85bd55, - 0x00000000ae3c2377, 0x00000000adf26ebb, 0x00000000ada89f2c, - 0x00000000ad5eb4d5, - 0x00000000ad14afc2, 0x00000000acca8ffd, 0x00000000ac805594, - 0x00000000ac360090, 0x00000000abeb90fe, 0x00000000aba106e9, - 0x00000000ab56625d, 0x00000000ab0ba364, 0x00000000aac0ca0b, - 0x00000000aa75d65d, - 0x00000000aa2ac865, 0x00000000a9dfa030, 0x00000000a9945dc9, - 0x00000000a949013a, 0x00000000a8fd8a91, 0x00000000a8b1f9d8, - 0x00000000a8664f1c, 0x00000000a81a8a68, 0x00000000a7ceabc7, - 0x00000000a782b345, - 0x00000000a736a0ef, 0x00000000a6ea74cf, 0x00000000a69e2ef2, - 0x00000000a651cf63, 0x00000000a605562f, 0x00000000a5b8c360, - 0x00000000a56c1702, 0x00000000a51f5123, 0x00000000a4d271cc, - 0x00000000a485790b, - 0x00000000a43866eb, 0x00000000a3eb3b77, 0x00000000a39df6bd, - 0x00000000a35098c7, 0x00000000a30321a2, 0x00000000a2b5915a, - 0x00000000a267e7fa, 0x00000000a21a258e, 0x00000000a1cc4a24, - 0x00000000a17e55c5, - 0x00000000a1304880, 0x00000000a0e2225f, 0x00000000a093e36f, - 0x00000000a0458bbb, 0x000000009ff71b50, 0x000000009fa8923a, - 0x000000009f59f086, 0x000000009f0b363e, 0x000000009ebc6370, - 0x000000009e6d7827, - 0x000000009e1e746f, 0x000000009dcf5856, 0x000000009d8023e6, - 0x000000009d30d72d, 0x000000009ce17236, 0x000000009c91f50e, - 0x000000009c425fc1, 0x000000009bf2b25b, 0x000000009ba2ece8, - 0x000000009b530f76, - 0x000000009b031a0f, 0x000000009ab30cc1, 0x000000009a62e797, - 0x000000009a12aa9f, 0x0000000099c255e5, 0x000000009971e974, - 0x000000009921655a, 0x0000000098d0c9a2, 0x0000000098801659, - 0x00000000982f4b8d, - 0x0000000097de6948, 0x00000000978d6f97, 0x00000000973c5e88, - 0x0000000096eb3626, 0x000000009699f67f, 0x0000000096489f9e, - 0x0000000095f73190, 0x0000000095a5ac61, 0x000000009554101f, - 0x0000000095025cd6, - 0x0000000094b09292, 0x00000000945eb161, 0x00000000940cb94e, - 0x0000000093baaa66, 0x00000000936884b6, 0x000000009316484b, - 0x0000000092c3f531, 0x0000000092718b75, 0x00000000921f0b24, - 0x0000000091cc744b, - 0x000000009179c6f5, 0x0000000091270331, 0x0000000090d4290a, - 0x000000009081388e, 0x00000000902e31c8, 0x000000008fdb14c7, - 0x000000008f87e197, 0x000000008f349845, 0x000000008ee138dd, - 0x000000008e8dc36c, - 0x000000008e3a3800, 0x000000008de696a5, 0x000000008d92df68, - 0x000000008d3f1256, 0x000000008ceb2f7c, 0x000000008c9736e7, - 0x000000008c4328a3, 0x000000008bef04bf, 0x000000008b9acb46, - 0x000000008b467c45, - 0x000000008af217cb, 0x000000008a9d9de3, 0x000000008a490e9b, - 0x0000000089f469ff, 0x00000000899fb01e, 0x00000000894ae103, - 0x0000000088f5fcbc, 0x0000000088a10357, 0x00000000884bf4df, - 0x0000000087f6d163, - 0x0000000087a198f0, 0x00000000874c4b92, 0x0000000086f6e956, - 0x0000000086a1724b, 0x00000000864be67c, 0x0000000085f645f8, - 0x0000000085a090cc, 0x00000000854ac704, 0x0000000084f4e8ad, - 0x00000000849ef5d7, - 0x000000008448ee8c, 0x0000000083f2d2db, 0x00000000839ca2d1, - 0x0000000083465e7c, 0x0000000082f005e8, 0x0000000082999922, - 0x0000000082431839, 0x0000000081ec833a, 0x000000008195da31, - 0x00000000813f1d2d, - 0x0000000080e84c3a, 0x0000000080916766, 0x00000000803a6ebf, - 0x000000007fe36251, 0x000000007f8c422b, 0x000000007f350e59, - 0x000000007eddc6ea, 0x000000007e866bea, 0x000000007e2efd67, - 0x000000007dd77b6f, - 0x000000007d7fe60f, 0x000000007d283d54, 0x000000007cd0814c, - 0x000000007c78b205, 0x000000007c20cf8c, 0x000000007bc8d9ef, - 0x000000007b70d13b, 0x000000007b18b57e, 0x000000007ac086c5, - 0x000000007a68451f, - 0x000000007a0ff098, 0x0000000079b7893e, 0x00000000795f0f1f, - 0x0000000079068248, 0x0000000078ade2c8, 0x00000000785530ab, - 0x0000000077fc6c01, 0x0000000077a394d5, 0x00000000774aab36, - 0x0000000076f1af32, - 0x000000007698a0d6, 0x00000000763f8030, 0x0000000075e64d4e, - 0x00000000758d083e, 0x000000007533b10d, 0x0000000074da47c9, - 0x000000007480cc80, 0x0000000074273f3f, 0x0000000073cda016, - 0x000000007373ef10, - 0x00000000731a2c3d, 0x0000000072c057aa, 0x0000000072667164, - 0x00000000720c797a, 0x0000000071b26ffa, 0x00000000715854f2, - 0x0000000070fe286e, 0x0000000070a3ea7e, 0x0000000070499b30, - 0x000000006fef3a90, - 0x000000006f94c8ae, 0x000000006f3a4596, 0x000000006edfb157, - 0x000000006e850c00, 0x000000006e2a559d, 0x000000006dcf8e3d, - 0x000000006d74b5ee, 0x000000006d19ccbe, 0x000000006cbed2bb, - 0x000000006c63c7f3, - 0x000000006c08ac74, 0x000000006bad804c, 0x000000006b524389, - 0x000000006af6f639, 0x000000006a9b986b, 0x000000006a402a2c, - 0x0000000069e4ab8a, 0x0000000069891c94, 0x00000000692d7d57, - 0x0000000068d1cde3, - 0x0000000068760e44, 0x00000000681a3e89, 0x0000000067be5ec1, - 0x0000000067626ef9, 0x0000000067066f40, 0x0000000066aa5fa3, - 0x00000000664e4032, 0x0000000065f210f9, 0x000000006595d209, - 0x000000006539836d, - 0x0000000064dd2536, 0x000000006480b770, 0x0000000064243a2b, - 0x0000000063c7ad75, 0x00000000636b115c, 0x00000000630e65ed, - 0x0000000062b1ab39, 0x000000006254e14c, 0x0000000061f80835, - 0x00000000619b2002, - 0x00000000613e28c2, 0x0000000060e12283, 0x0000000060840d54, - 0x000000006026e943, 0x000000005fc9b65d, 0x000000005f6c74b2, - 0x000000005f0f2450, 0x000000005eb1c545, 0x000000005e5457a0, - 0x000000005df6db6f, - 0x000000005d9950c0, 0x000000005d3bb7a3, 0x000000005cde1024, - 0x000000005c805a54, 0x000000005c22963f, 0x000000005bc4c3f6, - 0x000000005b66e385, 0x000000005b08f4fd, 0x000000005aaaf86a, - 0x000000005a4ceddc, - 0x0000000059eed561, 0x000000005990af08, 0x0000000059327adf, - 0x0000000058d438f4, 0x000000005875e957, 0x0000000058178c16, - 0x0000000057b9213f, 0x00000000575aa8e0, 0x0000000056fc230a, - 0x00000000569d8fc9, - 0x00000000563eef2d, 0x0000000055e04144, 0x000000005581861d, - 0x000000005522bdc6, 0x0000000054c3e84e, 0x00000000546505c4, - 0x0000000054061636, 0x0000000053a719b3, 0x000000005348104a, - 0x0000000052e8fa09, - 0x000000005289d6ff, 0x00000000522aa73a, 0x0000000051cb6aca, - 0x00000000516c21bc, 0x00000000510ccc20, 0x0000000050ad6a05, - 0x00000000504dfb78, 0x000000004fee808a, 0x000000004f8ef947, - 0x000000004f2f65c0, - 0x000000004ecfc603, 0x000000004e701a1f, 0x000000004e106222, - 0x000000004db09e1b, 0x000000004d50ce19, 0x000000004cf0f22b, - 0x000000004c910a5f, 0x000000004c3116c5, 0x000000004bd1176b, - 0x000000004b710c5f, - 0x000000004b10f5b2, 0x000000004ab0d371, 0x000000004a50a5ab, - 0x0000000049f06c70, 0x00000000499027cd, 0x00000000492fd7d3, - 0x0000000048cf7c8f, 0x00000000486f1611, 0x00000000480ea467, - 0x0000000047ae27a1, - 0x00000000474d9fcd, 0x0000000046ed0cfa, 0x00000000468c6f37, - 0x00000000462bc693, 0x0000000045cb131c, 0x00000000456a54e3, - 0x0000000045098bf5, 0x0000000044a8b861, 0x000000004447da37, - 0x0000000043e6f186, - 0x000000004385fe5c, 0x00000000432500c8, 0x0000000042c3f8d9, - 0x000000004262e69f, 0x000000004201ca28, 0x0000000041a0a383, - 0x00000000413f72bf, 0x0000000040de37eb, 0x00000000407cf317, - 0x00000000401ba450, - 0x000000003fba4ba7, 0x000000003f58e92a, 0x000000003ef77ce8, - 0x000000003e9606f1, 0x000000003e348752, 0x000000003dd2fe1c, - 0x000000003d716b5e, 0x000000003d0fcf25, 0x000000003cae2982, - 0x000000003c4c7a83, - 0x000000003beac238, 0x000000003b8900b0, 0x000000003b2735f9, - 0x000000003ac56223, 0x000000003a63853d, 0x000000003a019f56, - 0x00000000399fb07d, 0x00000000393db8c1, 0x0000000038dbb831, - 0x000000003879aedd, - 0x0000000038179cd3, 0x0000000037b58222, 0x0000000037535edb, - 0x0000000036f1330b, 0x00000000368efec2, 0x00000000362cc20f, - 0x0000000035ca7d02, 0x0000000035682fa9, 0x000000003505da14, - 0x0000000034a37c51, - 0x0000000034411671, 0x0000000033dea881, 0x00000000337c3292, - 0x000000003319b4b3, 0x0000000032b72ef2, 0x000000003254a15e, - 0x0000000031f20c08, 0x00000000318f6efe, 0x00000000312cca50, - 0x0000000030ca1e0c, - 0x0000000030676a43, 0x000000003004af02, 0x000000002fa1ec5a, - 0x000000002f3f2259, 0x000000002edc510f, 0x000000002e79788b, - 0x000000002e1698dc, 0x000000002db3b212, 0x000000002d50c43c, - 0x000000002cedcf68, - 0x000000002c8ad3a7, 0x000000002c27d108, 0x000000002bc4c799, - 0x000000002b61b76b, 0x000000002afea08c, 0x000000002a9b830b, - 0x000000002a385ef9, 0x0000000029d53464, 0x000000002972035b, - 0x00000000290ecbee, - 0x0000000028ab8e2c, 0x0000000028484a25, 0x0000000027e4ffe7, - 0x000000002781af83, 0x00000000271e5906, 0x0000000026bafc82, - 0x0000000026579a04, 0x0000000025f4319d, 0x000000002590c35c, - 0x00000000252d4f4f, - 0x0000000024c9d587, 0x0000000024665613, 0x000000002402d101, - 0x00000000239f4662, 0x00000000233bb644, 0x0000000022d820b8, - 0x00000000227485cc, 0x000000002210e590, 0x0000000021ad4013, - 0x0000000021499565, - 0x0000000020e5e594, 0x00000000208230b1, 0x00000000201e76ca, - 0x000000001fbab7ef, 0x000000001f56f430, 0x000000001ef32b9b, - 0x000000001e8f5e41, 0x000000001e2b8c30, 0x000000001dc7b578, - 0x000000001d63da29, - 0x000000001cfffa51, 0x000000001c9c1600, 0x000000001c382d46, - 0x000000001bd44032, 0x000000001b704ed3, 0x000000001b0c5939, - 0x000000001aa85f74, 0x000000001a446191, 0x0000000019e05fa2, - 0x00000000197c59b5, - 0x0000000019184fdb, 0x0000000018b44221, 0x0000000018503098, - 0x0000000017ec1b50, 0x0000000017880257, 0x000000001723e5bd, - 0x0000000016bfc591, 0x00000000165ba1e4, 0x0000000015f77ac3, - 0x0000000015935040, - 0x00000000152f2269, 0x0000000014caf14d, 0x000000001466bcfd, - 0x0000000014028587, 0x00000000139e4afb, 0x00000000133a0d69, - 0x0000000012d5cce0, 0x000000001271896f, 0x00000000120d4326, - 0x0000000011a8fa15, - 0x000000001144ae4a, 0x0000000010e05fd6, 0x00000000107c0ec7, - 0x000000001017bb2d, 0x000000000fb36519, 0x000000000f4f0c98, - 0x000000000eeab1bb, 0x000000000e865491, 0x000000000e21f52a, - 0x000000000dbd9395, - 0x000000000d592fe1, 0x000000000cf4ca1f, 0x000000000c90625c, - 0x000000000c2bf8aa, 0x000000000bc78d18, 0x000000000b631fb4, - 0x000000000afeb08f, 0x000000000a9a3fb8, 0x000000000a35cd3e, - 0x0000000009d15931, - 0x00000000096ce3a1, 0x0000000009086c9c, 0x0000000008a3f433, - 0x00000000083f7a75, 0x0000000007daff71, 0x0000000007768337, - 0x00000000071205d6, 0x0000000006ad875f, 0x00000000064907df, - 0x0000000005e48768, - 0x0000000005800608, 0x00000000051b83cf, 0x0000000004b700cc, - 0x0000000004527d0f, 0x0000000003edf8a7, 0x00000000038973a4, - 0x000000000324ee16, 0x0000000002c0680b, 0x00000000025be194, - 0x0000000001f75ac0, - 0x000000000192d39e, 0x00000000012e4c3e, 0x0000000000c9c4af, - 0x0000000000653d02, 0x0000000000000000 -}; - -EAPI Eina_F32p32 eina_f32p32_cos(Eina_F32p32 a) -{ - Eina_F32p32 F32P32_2PI; - Eina_F32p32 F32P32_PI2; - Eina_F32p32 F32P32_3PI2; - Eina_F32p32 remainder_2PI; - Eina_F32p32 remainder_PI; - Eina_F32p32 interpol; - Eina_F32p32 result; - int idx; - int index2; - - F32P32_2PI = EINA_F32P32_PI << 1; - F32P32_PI2 = EINA_F32P32_PI >> 1; - F32P32_3PI2 = EINA_F32P32_PI + F32P32_PI2; - - /* Take advantage of cosinus symetrie. */ - a = eina_fp32p32_llabs(a); - - /* Find table entry in 0 to PI / 2 */ - remainder_PI = a - (a / EINA_F32P32_PI) * EINA_F32P32_PI; - - /* Find which case from 0 to 2 * PI */ - remainder_2PI = a - (a / F32P32_2PI) * F32P32_2PI; - - interpol = - eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2), - EINA_F32P32_PI); - idx = eina_f32p32_int_to(interpol); - if (idx >= MAX_PREC) - idx = 2 * MAX_PREC - (idx - 1); - - index2 = idx + 1; - if (index2 == MAX_PREC) - index2 = idx - 1; - - result = eina_f32p32_add(eina_trigo[idx], - eina_f32p32_mul(eina_f32p32_sub - (eina_trigo[idx], - eina_trigo[index2]), - (Eina_F32p32) - eina_f32p32_fracc_get - (interpol))); - - if (0 <= remainder_2PI && remainder_2PI < F32P32_PI2) - return result; - else if (F32P32_PI2 <= remainder_2PI - && remainder_2PI < EINA_F32P32_PI) - return -result; - else if (EINA_F32P32_PI <= remainder_2PI - && remainder_2PI < F32P32_3PI2) - return -result; - else /* if (F32P32_3PI2 <= remainder_2PI) */ - return result; -} - -EAPI Eina_F32p32 eina_f32p32_sin(Eina_F32p32 a) -{ - Eina_F32p32 F32P32_2PI; - Eina_F32p32 F32P32_PI2; - Eina_F32p32 F32P32_3PI2; - Eina_F32p32 remainder_2PI; - Eina_F32p32 remainder_PI; - Eina_F32p32 interpol; - Eina_F32p32 result; - int idx; - int index2; - - F32P32_2PI = EINA_F32P32_PI << 1; - F32P32_PI2 = EINA_F32P32_PI >> 1; - F32P32_3PI2 = EINA_F32P32_PI + F32P32_PI2; - - /* We only have a table for cosinus, but sin(a) = cos(pi / 2 - a) */ - a = eina_f32p32_sub(F32P32_PI2, a); - - /* Take advantage of cosinus symetrie. */ - a = eina_fp32p32_llabs(a); - - /* Find table entry in 0 to PI / 2 */ - remainder_PI = a - (a / EINA_F32P32_PI) * EINA_F32P32_PI; - - /* Find which case from 0 to 2 * PI */ - remainder_2PI = a - (a / F32P32_2PI) * F32P32_2PI; - - interpol = - eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2), - EINA_F32P32_PI); - idx = eina_f32p32_int_to(interpol); - if (idx >= MAX_PREC) - idx = 2 * MAX_PREC - (idx + 1); - - index2 = idx + 1; - if (index2 == MAX_PREC) - index2 = idx - 1; - - result = eina_f32p32_add(eina_trigo[idx], - eina_f32p32_mul(eina_f32p32_sub - (eina_trigo[idx], - eina_trigo[index2]), - (Eina_F32p32) - eina_f32p32_fracc_get - (interpol))); - - if (0 <= remainder_2PI && remainder_2PI < F32P32_PI2) - return result; - else if (F32P32_PI2 <= remainder_2PI - && remainder_2PI < EINA_F32P32_PI) - return -result; - else if (EINA_F32P32_PI <= remainder_2PI - && remainder_2PI < F32P32_3PI2) - return -result; - else /* if (F32P32_3PI2 <= remainder_2PI) */ - return result; -} diff --git a/tests/suite/ecore/src/lib/eina_hamster.c b/tests/suite/ecore/src/lib/eina_hamster.c deleted file mode 100644 index 2c462f1e4a..0000000000 --- a/tests/suite/ecore/src/lib/eina_hamster.c +++ /dev/null @@ -1,125 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <string.h> - -#include "eina_config.h" -#include "eina_types.h" -#include "eina_hamster.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -const char *_eina_hamster_time = __TIME__; -const char *_eina_hamster_date = __DATE__; -static int _eina_hamsters = -1; - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Hamster_Group Hamster - * - * @brief These functions provide hamster calls. - * - * @{ - */ - -/** - * @brief Get the hamster count. - * - * @return The number of available hamsters. - * - * This function returns how many hamsters you have. - */ -EAPI int eina_hamster_count(void) -{ - if (_eina_hamsters < 0) { - int hrs = 0, min = 0, sec = 0; - char mon[8] = ""; - int monnum = 0, day = 0, year = 0; - int fields; - - fields = - sscanf(_eina_hamster_time, "%02i:%02i:%02i", &hrs, - &min, &sec); - if (fields == 3) { - _eina_hamsters = (hrs * 60) + min; - fields = - sscanf(_eina_hamster_date, "%s %i %i", mon, - &day, &year); - if (fields == 3) { - int i; - const char *mons[] = { - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec" - }; - - for (i = 0; i < 12; i++) { - if (!strcmp(mon, mons[i])) { - monnum = i + 1; - break; - } - } - // alloc 60 for mins, 24 for hrs - // alloc 1-31 (32) for days, 1-12 (13) for months - // use year as-is, for 31 bits (signed) this gives us up to - // 3584 years, which is good enough imho. - 1500 years from - // now or so. :) - _eina_hamsters += - (day + (monnum * 32) + - (13 * 32 * year)) * (24 * 60); - } - } - } - // format: [rest - year][0-12 - month][0-31 - day][0-23 - hrs][0-59 - sec] - return _eina_hamsters; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_hash.c b/tests/suite/ecore/src/lib/eina_hash.c deleted file mode 100644 index f75a150f87..0000000000 --- a/tests/suite/ecore/src/lib/eina_hash.c +++ /dev/null @@ -1,1897 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Gustavo Sverzut Barbieri, - * Vincent Torri, Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef _MSC_VER -#include <Evil.h> -#else -#include <stdint.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_rbtree.h" -#include "eina_error.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_hash.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -#define EINA_MAGIC_CHECK_HASH(d) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_HASH)) { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_HASH); } \ - } while(0) - -#define EINA_MAGIC_CHECK_HASH_ITERATOR(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_HASH_ITERATOR)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_HASH_ITERATOR); \ - return __VA_ARGS__; \ - } \ - } while(0) - -#define EINA_HASH_BUCKET_SIZE 8 -#define EINA_HASH_SMALL_BUCKET_SIZE 5 - -#define EINA_HASH_RBTREE_MASK 0xFFF - -typedef struct _Eina_Hash_Head Eina_Hash_Head; -typedef struct _Eina_Hash_Element Eina_Hash_Element; -typedef struct _Eina_Hash_Foreach_Data Eina_Hash_Foreach_Data; -typedef struct _Eina_Iterator_Hash Eina_Iterator_Hash; -typedef struct _Eina_Hash_Each Eina_Hash_Each; - -struct _Eina_Hash { - Eina_Key_Length key_length_cb; - Eina_Key_Cmp key_cmp_cb; - Eina_Key_Hash key_hash_cb; - Eina_Free_Cb data_free_cb; - - Eina_Rbtree **buckets; - int size; - int mask; - - int population; - - EINA_MAGIC}; - -struct _Eina_Hash_Head { - EINA_RBTREE; - int hash; - - Eina_Rbtree *head; -}; - -struct _Eina_Hash_Element { - EINA_RBTREE; - Eina_Hash_Tuple tuple; - Eina_Bool begin:1; -}; - -struct _Eina_Hash_Foreach_Data { - Eina_Hash_Foreach cb; - const void *fdata; -}; - -typedef void *(*Eina_Iterator_Get_Content_Callback) (Eina_Iterator_Hash * - it); -#define FUNC_ITERATOR_GET_CONTENT(Function) ((Eina_Iterator_Get_Content_Callback)Function) - -struct _Eina_Iterator_Hash { - Eina_Iterator iterator; - - Eina_Iterator_Get_Content_Callback get_content; - const Eina_Hash *hash; - - Eina_Iterator *current; - Eina_Iterator *list; - Eina_Hash_Head *hash_head; - Eina_Hash_Element *hash_element; - int bucket; - - int index; - - EINA_MAGIC}; - -struct _Eina_Hash_Each { - Eina_Hash_Head *hash_head; - const Eina_Hash_Element *hash_element; - const void *data; -}; - -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ - + (uint32_t)(((const uint8_t *)(d))[0])) - -static inline int -_eina_hash_hash_rbtree_cmp_hash(const Eina_Hash_Head * hash_head, - const int *hash, - __UNUSED__ int key_length, - __UNUSED__ void *data) -{ - return hash_head->hash - *hash; -} - -static Eina_Rbtree_Direction -_eina_hash_hash_rbtree_cmp_node(const Eina_Hash_Head * left, - const Eina_Hash_Head * right, - __UNUSED__ void *data) -{ - if (left->hash - right->hash < 0) - return EINA_RBTREE_LEFT; - - return EINA_RBTREE_RIGHT; -} - -static inline int -_eina_hash_key_rbtree_cmp_key_data(const Eina_Hash_Element * hash_element, - const Eina_Hash_Tuple * tuple, - __UNUSED__ unsigned int key_length, - Eina_Key_Cmp cmp) -{ - int result; - - result = cmp(hash_element->tuple.key, - hash_element->tuple.key_length, - tuple->key, tuple->key_length); - - if (result == 0 && tuple->data - && tuple->data != hash_element->tuple.data) - return 1; - - return result; -} - -static Eina_Rbtree_Direction -_eina_hash_key_rbtree_cmp_node(const Eina_Hash_Element * left, - const Eina_Hash_Element * right, - Eina_Key_Cmp cmp) -{ - int result; - - result = cmp(left->tuple.key, left->tuple.key_length, - right->tuple.key, right->tuple.key_length); - - if (result < 0) - return EINA_RBTREE_LEFT; - - return EINA_RBTREE_RIGHT; -} - -static inline Eina_Bool -eina_hash_add_alloc_by_hash(Eina_Hash * hash, - const void *key, int key_length, - int alloc_length, int key_hash, - const void *data) -{ - Eina_Hash_Element *new_hash_element = NULL; - Eina_Hash_Head *hash_head; - Eina_Error error = 0; - int hash_num; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); - EINA_MAGIC_CHECK_HASH(hash); - - error = EINA_ERROR_OUT_OF_MEMORY; - - /* Apply eina mask to hash. */ - hash_num = key_hash & hash->mask; - key_hash &= EINA_HASH_RBTREE_MASK; - - if (!hash->buckets) { - hash->buckets = calloc(sizeof(Eina_Rbtree *), hash->size); - if (!hash->buckets) - goto on_error; - - hash_head = NULL; - } else - /* Look up for head node. */ - hash_head = - (Eina_Hash_Head *) eina_rbtree_inline_lookup(hash-> - buckets - [hash_num], - &key_hash, - 0, - EINA_RBTREE_CMP_KEY_CB - (_eina_hash_hash_rbtree_cmp_hash), - NULL); - - if (!hash_head) { - /* If not found allocate it and an element. */ - hash_head = - malloc(sizeof(Eina_Hash_Head) + - sizeof(Eina_Hash_Element) + alloc_length); - if (!hash_head) - goto on_error; - - hash_head->hash = key_hash; - hash_head->head = NULL; - - hash->buckets[hash_num] = - eina_rbtree_inline_insert(hash->buckets[hash_num], - EINA_RBTREE_GET(hash_head), - EINA_RBTREE_CMP_NODE_CB - (_eina_hash_hash_rbtree_cmp_node), - NULL); - - new_hash_element = (Eina_Hash_Element *) (hash_head + 1); - new_hash_element->begin = EINA_TRUE; - } - - if (!new_hash_element) { - /* - Alloc a new element - (No more lookup as we expect to support more than one item for one key). - */ - new_hash_element = - malloc(sizeof(Eina_Hash_Element) + alloc_length); - if (!new_hash_element) - goto on_error; - - new_hash_element->begin = EINA_FALSE; - } - - /* Setup the element */ - new_hash_element->tuple.key_length = key_length; - new_hash_element->tuple.data = (void *) data; - if (alloc_length > 0) { - new_hash_element->tuple.key = - (char *) (new_hash_element + 1); - memcpy((char *) new_hash_element->tuple.key, key, - alloc_length); - } else - new_hash_element->tuple.key = key; - - /* add the new element to the hash. */ - hash_head->head = - eina_rbtree_inline_insert(hash_head->head, - EINA_RBTREE_GET(new_hash_element), - EINA_RBTREE_CMP_NODE_CB - (_eina_hash_key_rbtree_cmp_node), - (const void *) hash->key_cmp_cb); - hash->population++; - return EINA_TRUE; - - on_error: - eina_error_set(error); - return EINA_FALSE; -} - -static Eina_Bool -_eina_hash_rbtree_each(__UNUSED__ const Eina_Rbtree * container, - const Eina_Hash_Head * hash_head, - Eina_Hash_Each * data) -{ - Eina_Iterator *it; - Eina_Hash_Element *hash_element; - Eina_Bool found = EINA_TRUE; - - it = eina_rbtree_iterator_prefix(hash_head->head); - EINA_ITERATOR_FOREACH(it, hash_element) { - if (hash_element->tuple.data == data->data) { - data->hash_element = hash_element; - data->hash_head = (Eina_Hash_Head *) hash_head; - found = EINA_FALSE; - break; - } - } - - eina_iterator_free(it); - return found; -} - -static inline Eina_Hash_Element *_eina_hash_find_by_hash(const Eina_Hash * - hash, - Eina_Hash_Tuple * - tuple, - int key_hash, - Eina_Hash_Head ** - hash_head) -{ - Eina_Hash_Element *hash_element; - int rb_hash = key_hash & EINA_HASH_RBTREE_MASK; - - key_hash &= hash->mask; - - if (!hash->buckets) - return NULL; - - *hash_head = - (Eina_Hash_Head *) eina_rbtree_inline_lookup(hash-> - buckets[key_hash], - &rb_hash, 0, - EINA_RBTREE_CMP_KEY_CB - (_eina_hash_hash_rbtree_cmp_hash), - NULL); - if (!*hash_head) - return NULL; - - hash_element = - (Eina_Hash_Element *) eina_rbtree_inline_lookup((*hash_head)-> - head, tuple, 0, - EINA_RBTREE_CMP_KEY_CB - (_eina_hash_key_rbtree_cmp_key_data), - (const void *) - hash->key_cmp_cb); - - return hash_element; -} - -static inline Eina_Hash_Element *_eina_hash_find_by_data(const Eina_Hash * - hash, - const void *data, - int *key_hash, - Eina_Hash_Head ** - hash_head) -{ - Eina_Hash_Each each; - Eina_Iterator *it; - int hash_num; - - if (!hash->buckets) - return NULL; - - each.hash_element = NULL; - each.data = data; - - for (hash_num = 0; hash_num < hash->size; hash_num++) { - if (!hash->buckets[hash_num]) - continue; - - it = eina_rbtree_iterator_prefix(hash->buckets[hash_num]); - eina_iterator_foreach(it, - EINA_EACH_CB(_eina_hash_rbtree_each), - &each); - eina_iterator_free(it); - - if (each.hash_element) { - *key_hash = hash_num; - *hash_head = each.hash_head; - return (Eina_Hash_Element *) each.hash_element; - } - } - - return NULL; -} - -static void -_eina_hash_el_free(Eina_Hash_Element * hash_element, Eina_Hash * hash) -{ - if (hash->data_free_cb) - hash->data_free_cb(hash_element->tuple.data); - - if (hash_element->begin == EINA_FALSE) - free(hash_element); -} - -static void -_eina_hash_head_free(Eina_Hash_Head * hash_head, Eina_Hash * hash) -{ - eina_rbtree_delete(hash_head->head, - EINA_RBTREE_FREE_CB(_eina_hash_el_free), hash); - free(hash_head); -} - -static Eina_Bool -_eina_hash_del_by_hash_el(Eina_Hash * hash, - Eina_Hash_Element * hash_element, - Eina_Hash_Head * hash_head, int key_hash) -{ - hash_head->head = - eina_rbtree_inline_remove(hash_head->head, - EINA_RBTREE_GET(hash_element), - EINA_RBTREE_CMP_NODE_CB - (_eina_hash_key_rbtree_cmp_node), - (const void *) hash->key_cmp_cb); - _eina_hash_el_free(hash_element, hash); - - if (!hash_head->head) { - key_hash &= hash->mask; - - hash->buckets[key_hash] = - eina_rbtree_inline_remove(hash->buckets[key_hash], - EINA_RBTREE_GET(hash_head), - EINA_RBTREE_CMP_NODE_CB - (_eina_hash_hash_rbtree_cmp_node), - NULL); - free(hash_head); - } - - hash->population--; - if (hash->population == 0) { - free(hash->buckets); - hash->buckets = NULL; - } - - return EINA_TRUE; -} - -static Eina_Bool -_eina_hash_del_by_key_hash(Eina_Hash * hash, - const void *key, - int key_length, int key_hash, const void *data) -{ - Eina_Hash_Element *hash_element; - Eina_Hash_Head *hash_head; - Eina_Hash_Tuple tuple; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); - EINA_MAGIC_CHECK_HASH(hash); - - if (!hash->buckets) - return EINA_FALSE; - - tuple.key = (void *) key; - tuple.key_length = key_length; - tuple.data = (void *) data; - - hash_element = - _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); - if (!hash_element) - return EINA_FALSE; - - return _eina_hash_del_by_hash_el(hash, hash_element, hash_head, - key_hash); -} - -static Eina_Bool -_eina_hash_del_by_key(Eina_Hash * hash, const void *key, const void *data) -{ - int key_length, key_hash; - - EINA_MAGIC_CHECK_HASH(hash); - if (!hash) - return EINA_FALSE; - - if (!key) - return EINA_FALSE; - - if (!hash->buckets) - return EINA_FALSE; - - key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; - key_hash = hash->key_hash_cb(key, key_length); - return _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, - data); -} - -static unsigned int _eina_string_key_length(const char *key) -{ - if (!key) - return 0; - - return (int) strlen(key) + 1; -} - -static int -_eina_string_key_cmp(const char *key1, __UNUSED__ int key1_length, - const char *key2, __UNUSED__ int key2_length) -{ - return strcmp(key1, key2); -} - -static int -_eina_stringshared_key_cmp(const char *key1, __UNUSED__ int key1_length, - const char *key2, __UNUSED__ int key2_length) -{ - return key1 - key2; -} - -static unsigned int _eina_int32_key_length(__UNUSED__ const uint32_t * key) -{ - return 4; -} - -static int -_eina_int32_key_cmp(const uint32_t * key1, __UNUSED__ int key1_length, - const uint32_t * key2, __UNUSED__ int key2_length) -{ - return *key1 - *key2; -} - -static unsigned int _eina_int64_key_length(__UNUSED__ const uint32_t * key) -{ - return 8; -} - -static int -_eina_int64_key_cmp(const uint64_t * key1, __UNUSED__ int key1_length, - const uint64_t * key2, __UNUSED__ int key2_length) -{ - return *key1 - *key2; -} - -static Eina_Bool -_eina_foreach_cb(const Eina_Hash * hash, - Eina_Hash_Tuple * data, Eina_Hash_Foreach_Data * fdata) -{ - return fdata->cb((Eina_Hash *) hash, - data->key, data->data, (void *) fdata->fdata); -} - -static void *_eina_hash_iterator_data_get_content(Eina_Iterator_Hash * it) -{ - Eina_Hash_Element *stuff; - - EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); - - stuff = it->hash_element; - - if (!stuff) - return NULL; - - return stuff->tuple.data; -} - -static void *_eina_hash_iterator_key_get_content(Eina_Iterator_Hash * it) -{ - Eina_Hash_Element *stuff; - - EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); - - stuff = it->hash_element; - - if (!stuff) - return NULL; - - return (void *) stuff->tuple.key; -} - -static Eina_Hash_Tuple - *_eina_hash_iterator_tuple_get_content(Eina_Iterator_Hash * it) -{ - Eina_Hash_Element *stuff; - - EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); - - stuff = it->hash_element; - - if (!stuff) - return NULL; - - return &stuff->tuple; -} - -static Eina_Bool -_eina_hash_iterator_next(Eina_Iterator_Hash * it, void **data) -{ - Eina_Bool ok; - int bucket; - - if (!(it->index < it->hash->population)) - return EINA_FALSE; - - if (!it->current) { - ok = EINA_FALSE; - bucket = 0; - it->index = -1; - } else { - ok = eina_iterator_next(it->list, - (void **) &it->hash_element); - if (!ok) { - eina_iterator_free(it->list); - it->list = NULL; - - ok = eina_iterator_next(it->current, - (void **) &it->hash_head); - if (!ok) { - eina_iterator_free(it->current); - it->current = NULL; - it->bucket++; - } else { - it->list = - eina_rbtree_iterator_prefix(it-> - hash_head-> - head); - ok = eina_iterator_next(it->list, - (void **) &it-> - hash_element); - } - } - - bucket = it->bucket; - } - - if (ok == EINA_FALSE) { - while (bucket < it->hash->size) { - if (it->hash->buckets[bucket]) { - it->current = - eina_rbtree_iterator_prefix(it->hash-> - buckets - [bucket]); - ok = eina_iterator_next(it->current, - (void **) &it-> - hash_head); - if (ok) - break; - - eina_iterator_free(it->current); - it->current = NULL; - } - - ++bucket; - } - if (it->list) - eina_iterator_free(it->list); - - it->list = - eina_rbtree_iterator_prefix(it->hash_head->head); - ok = eina_iterator_next(it->list, - (void **) &it->hash_element); - if (bucket == it->hash->size) - ok = EINA_FALSE; - } - - it->index++; - it->bucket = bucket; - - if (ok) - *data = it->get_content(it); - - return ok; -} - -static void *_eina_hash_iterator_get_container(Eina_Iterator_Hash * it) -{ - EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); - return (void *) it->hash; -} - -static void _eina_hash_iterator_free(Eina_Iterator_Hash * it) -{ - EINA_MAGIC_CHECK_HASH_ITERATOR(it); - if (it->current) - eina_iterator_free(it->current); - - if (it->list) - eina_iterator_free(it->list); - - free(it); -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Hash_Group Hash Table - * - * @brief give a small description here : what it is for, what it does - * , etc... - * - * Hash API. Give some hints about the use (functions that must be - * used like init / shutdown), general use, etc... Give also a link to - * tutorial below. - * - * @section hashtable_algo Algorithm - * - * Give here the algorithm used in the implementation - * - * @section hashtable_perf Performance - * - * Give some hints about performance if it is possible, and an image ! - * - * @section hashtable_tutorial Tutorial - * - * Here is a fantastic tutorial about our hash table - * - * @{ - */ - -/** - * @brief Create a new hash table. - * - * @param key_length_cb The function called when getting the size of the key. - * @param key_cmp_cb The function called when comparing the keys. - * @param key_hash_cb The function called when getting the values. - * @param data_free_cb The function called when the hash table is freed. - * @param buckets_power_size The size of the buckets. - * @return The new hash table. - * - * This function create a new hash table using user-defined callbacks - * to manage the hash table. On failure, @c NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. If @p key_cmp_cb or @pkey_hash_cb - * are @c NULL, @c NULL is returned. If @p buckets_power_size is - * smaller or equal than 2, or if it is greater or equal than 17, - * @c NULL is returned. - * - * Pre-defined functions are available to create a hash table. See - * eina_hash_string_djb2_new(), eina_hash_string_superfast_new(), - * eina_hash_string_small_new(), eina_hash_int32_new(), - * eina_hash_int64_new(), eina_hash_pointer_new() and - * eina_hash_stringshared_new(). - */ -EAPI Eina_Hash *eina_hash_new(Eina_Key_Length key_length_cb, - Eina_Key_Cmp key_cmp_cb, - Eina_Key_Hash key_hash_cb, - Eina_Free_Cb data_free_cb, - int buckets_power_size) -{ - /* FIXME: Use mempool. */ - Eina_Hash *new; - - eina_error_set(0); - EINA_SAFETY_ON_NULL_RETURN_VAL(key_cmp_cb, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(key_hash_cb, NULL); - EINA_SAFETY_ON_TRUE_RETURN_VAL(buckets_power_size < 3, NULL); - EINA_SAFETY_ON_TRUE_RETURN_VAL(buckets_power_size > 16, NULL); - - new = malloc(sizeof(Eina_Hash)); - if (!new) - goto on_error; - - EINA_MAGIC_SET(new, EINA_MAGIC_HASH); - - new->key_length_cb = key_length_cb; - new->key_cmp_cb = key_cmp_cb; - new->key_hash_cb = key_hash_cb; - new->data_free_cb = data_free_cb; - new->buckets = NULL; - new->population = 0; - - new->size = 1 << buckets_power_size; - new->mask = new->size - 1; - - return new; - - on_error: - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; -} - -/** - * @brief Create a new hash table using the djb2 algorithm. - * - * @param data_free_cb The function called when the hash table is freed. - * @return The new hash table. - * - * This function create a new hash table using the djb2 algorithm for - * table management and strcmp() to compare the keys. Values can then - * be looked up with pointers other than the original key pointer that - * was used to add values. On failure, this function returns @c NULL. - * @p data_free_cb is a callback called when the hash table is - * freed. @c NULL can be passed as callback. - */ -EAPI Eina_Hash *eina_hash_string_djb2_new(Eina_Free_Cb data_free_cb) -{ - return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length), - EINA_KEY_CMP(_eina_string_key_cmp), - EINA_KEY_HASH(eina_hash_djb2), - data_free_cb, EINA_HASH_BUCKET_SIZE); -} - -/** - * @brief Create a new hash table for use with strings. - * - * @param data_free_cb The function called when the hash table is freed. - * @return The new hash table. - * - * This function create a new hash table using the superfast algorithm - * for table management and strcmp() to compare the keys. Values can - * then be looked up with pointers other than the original key pointer - * that was used to add values. On failure, this function returns - * @c NULL. @p data_free_cb is a callback called when the hash table is - * freed. @c NULL can be passed as callback. - */ -EAPI Eina_Hash *eina_hash_string_superfast_new(Eina_Free_Cb data_free_cb) -{ - return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length), - EINA_KEY_CMP(_eina_string_key_cmp), - EINA_KEY_HASH(eina_hash_superfast), - data_free_cb, EINA_HASH_BUCKET_SIZE); -} - -/** - * @brief Create a new hash table for use with strings with small bucket size. - * - * @param data_free_cb The function called when the hash table is freed. - * @return The new hash table. - * - * This function create a new hash table using the superfast algorithm - * for table management and strcmp() to compare the keys, but with a - * smaller bucket size (compared to eina_hash_string_superfast_new()) - * which will minimize the memory used by the returned hash - * table. Values can then be looked up with pointers other than the - * original key pointer that was used to add values. On failure, this - * function returns @c NULL. @p data_free_cb is a callback called when - * the hash table is freed. @c NULL can be passed as callback. - */ -EAPI Eina_Hash *eina_hash_string_small_new(Eina_Free_Cb data_free_cb) -{ - return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length), - EINA_KEY_CMP(_eina_string_key_cmp), - EINA_KEY_HASH(eina_hash_superfast), - data_free_cb, EINA_HASH_SMALL_BUCKET_SIZE); -} - -/** - * @brief Create a new hash table for use with 32bit integers. - * - * @param data_free_cb The function called when the hash table is freed. - * @return The new hash table. - * - * This function create a new hash table using the int32 algorithm for - * table management and dereferenced pointers to compare the - * keys. Values can then be looked up with pointers other than the - * original key pointer that was used to add values. This method may - * appear to be able to match string keys, actually it only matches - * the first character. On failure, this function returns @c NULL. - * @p data_free_cb is a callback called when the hash table is freed. - * @c NULL can be passed as callback. - */ -EAPI Eina_Hash *eina_hash_int32_new(Eina_Free_Cb data_free_cb) -{ - return eina_hash_new(EINA_KEY_LENGTH(_eina_int32_key_length), - EINA_KEY_CMP(_eina_int32_key_cmp), - EINA_KEY_HASH(eina_hash_int32), - data_free_cb, EINA_HASH_BUCKET_SIZE); -} - -/** - * @brief Create a new hash table for use with 64bit integers. - * - * @param data_free_cb The function called when the hash table is freed. - * @return The new hash table. - * - * This function create a new hash table using the int64 algorithm for - * table management and dereferenced pointers to compare the - * keys. Values can then be looked up with pointers other than the - * original key pointer that was used to add values. This method may - * appear to be able to match string keys, actually it only matches - * the first character. On failure, this function returns @c NULL. - * @p data_free_cb is a callback called when the hash table is freed. - * @c NULL can be passed as callback. - */ -EAPI Eina_Hash *eina_hash_int64_new(Eina_Free_Cb data_free_cb) -{ - return eina_hash_new(EINA_KEY_LENGTH(_eina_int64_key_length), - EINA_KEY_CMP(_eina_int64_key_cmp), - EINA_KEY_HASH(eina_hash_int64), - data_free_cb, EINA_HASH_BUCKET_SIZE); -} - -/** - * @brief Create a new hash table for use with pointers. - * - * @param data_free_cb The function called when the hash table is freed. - * @return The new hash table. - * - * This function create a new hash table using the int64 algorithm for - * table management and dereferenced pointers to compare the - * keys. Values can then be looked up with pointers other than the - * original key pointer that was used to add values. This method may - * appear to be able to match string keys, actually it only matches - * the first character. On failure, this function returns @c NULL. - * @p data_free_cb is a callback called when the hash table is freed. - * @c NULL can be passed as callback. - */ -EAPI Eina_Hash *eina_hash_pointer_new(Eina_Free_Cb data_free_cb) -{ -#ifdef __LP64__ - return eina_hash_new(EINA_KEY_LENGTH(_eina_int64_key_length), - EINA_KEY_CMP(_eina_int64_key_cmp), - EINA_KEY_HASH(eina_hash_int64), - data_free_cb, EINA_HASH_BUCKET_SIZE); -#else - return eina_hash_new(EINA_KEY_LENGTH(_eina_int32_key_length), - EINA_KEY_CMP(_eina_int32_key_cmp), - EINA_KEY_HASH(eina_hash_int32), - data_free_cb, EINA_HASH_BUCKET_SIZE); -#endif -} - -/** - * @brief Create a new hash table optimized for stringshared values. - * - * @param data_free_cb The function called when the hash table is freed. - * @return The new hash table. - * - * This function create a new hash table optimized for stringshared - * values. Values CAN NOT be looked up with pointers not - * equal to the original key pointer that was used to add a value. On failure, this function returns @c NULL. - * @p data_free_cb is a callback called when the hash table is freed. - * @c NULL can be passed as callback. - * - * Excerpt of code that will NOT work with this type of hash: - * - * @code - * extern Eina_Hash *hash; - * extern const char *value; - * const char *a = eina_stringshare_add("key"); - * - * eina_hash_add(hash, a, value); - * eina_hash_find(hash, "key") - * @endcode - */ -EAPI Eina_Hash *eina_hash_stringshared_new(Eina_Free_Cb data_free_cb) -{ - return eina_hash_new(NULL, - EINA_KEY_CMP(_eina_stringshared_key_cmp), - EINA_KEY_HASH(eina_hash_superfast), - data_free_cb, EINA_HASH_BUCKET_SIZE); -} - -/** - * @brief Returns the number of entries in the given hash table. - * - * @param hash The given hash table. - * @return The number of entries in the hash table. - * - * This function returns the number of entries in @p hash, or 0 on - * error. If @p hash is @c NULL, 0 is returned. - */ -EAPI int eina_hash_population(const Eina_Hash * hash) -{ - if (!hash) - return 0; - - EINA_MAGIC_CHECK_HASH(hash); - return hash->population; -} - -/** - * Free the given hash table resources. - * - * @param hash The hash table to be freed. - * - * This function frees up all the memory allocated to storing @p hash, - * and call the free callback if it has been passed to the hash table - * at creation time. If no free callback has been passed, 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 - * already freed any allocated data in the hash table or has the - * pointers for data in the table stored elsewhere as well. If @p hash - * is @c NULL, the function returns immediately. - * - * Example: - * @code - * extern Eina_Hash *hash; - * - * eina_hash_free(hash); - * hash = NULL; - * @endcode - */ -EAPI void eina_hash_free(Eina_Hash * hash) -{ - int i; - - EINA_MAGIC_CHECK_HASH(hash); - EINA_SAFETY_ON_NULL_RETURN(hash); - - if (hash->buckets) { - for (i = 0; i < hash->size; i++) - eina_rbtree_delete(hash->buckets[i], - EINA_RBTREE_FREE_CB - (_eina_hash_head_free), hash); - free(hash->buckets); - } - free(hash); -} - -/** - * Free the given hash table buckets resources. - * - * @param hash The hash table whose buckets have to be freed. - * - * This function frees up all the memory allocated to storing the - * buckets of @p hash, and call the free callback on all hash table - * buckets if it has been passed to the hash table at creation time, - * then frees the buckets. If no free callback has been passed, no - * buckets value will be freed. If @p hash is @c NULL, the function - * returns immediately. - */ -EAPI void eina_hash_free_buckets(Eina_Hash * hash) -{ - int i; - - EINA_MAGIC_CHECK_HASH(hash); - EINA_SAFETY_ON_NULL_RETURN(hash); - - if (hash->buckets) { - for (i = 0; i < hash->size; i++) - eina_rbtree_delete(hash->buckets[i], - EINA_RBTREE_FREE_CB - (_eina_hash_head_free), hash); - free(hash->buckets); - hash->buckets = NULL; - hash->population = 0; - } -} - -/** - * @brief Add an entry to the given hash table. - * - * @param hash The given hash table. - * @param key A unique key. - * @param key_length The length of the key. - * @param key_hash The hash that will always match key. - * @param data The data to associate with the string given by the key. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function adds @p key to @p hash. @p hash, @p key and @p data - * can be @c NULL, in that case #EINA_FALSE is returned. @p key is - * expected to be a unique string within the hash table. Otherwise, - * one cannot be sure which inserted data pointer will be accessed - * with @ref eina_hash_find, and removed with @ref eina_hash_del. Do - * not forget to count '\\0' for string when setting the value of - * @p key_length. @p key_hash is expected to always match - * @p key. Otherwise, one cannot be sure to find it again with @ref - * eina_hash_find_by_hash. Key strings are case sensitive. If an error - * occurs, eina_error_get() should be used to determine if an - * allocation error occurred during this function. This function - * returns #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_hash_add_by_hash(Eina_Hash * hash, - const void *key, - int key_length, int key_hash, const void *data) -{ - return eina_hash_add_alloc_by_hash(hash, - key, - key_length, - key_length, key_hash, data); -} - -/** - * @brief Add an entry to the given hash table and do not duplicate the string key. - * - * @param hash The given hash table. Can be @c NULL. - * @param key A unique key. Can be @c NULL. - * @param key_length Should be the length of @p key (don't forget to count '\\0' for string). - * @param key_hash The hash that will always match key. - * @param data Data to associate with the string given by @p key. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function adds @p key to @p hash. @p hash, @p key and @p data - * can be @c NULL, in that case #EINA_FALSE is returned. @p key is - * expected to be a unique string within the hash table. Otherwise, - * one cannot be sure which inserted data pointer will be accessed - * with @ref eina_hash_find, and removed with @ref eina_hash_del. This - * function does not make a copy of @p key so it must be a string - * constant or stored elsewhere (in the object being added). Do - * not forget to count '\\0' for string when setting the value of - * @p key_length. @p key_hash is expected to always match - * @p key. Otherwise, one cannot be sure to find it again with @ref - * eina_hash_find_by_hash. Key strings are case sensitive. If an error - * occurs, eina_error_get() should be used to determine if an - * allocation error occurred during this function. This function - * returns #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_hash_direct_add_by_hash(Eina_Hash * hash, - const void *key, - int key_length, - int key_hash, const void *data) -{ - return eina_hash_add_alloc_by_hash(hash, key, key_length, 0, - key_hash, data); -} - -/** - * @brief Add an entry to the given hash table. - * - * @param hash The given hash table. - * @param key A unique key. - * @param data Data to associate with the string given by @p key. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function adds @p key to @p hash. @p hash, @p key and @p data - * can be @c NULL, in that case #EINA_FALSE is returned. @p key is - * expected to be unique within the hash table. Key uniqueness varies - * depending on the type of @p hash: a stringshared @ref Eina_Hash - * need only have unique pointers for keys, but the strings in the - * pointers may be identical. All other hash types require the strings - * themselves to be unique. Failure to use sufficient uniqueness will - * result in unexpected results when inserting data pointers accessed - * with eina_hash_find(), and removed with eina_hash_del(). Key - * strings are case sensitive. If an error occurs, eina_error_get() - * should be used to determine if an allocation error occurred during - * this function. This function returns #EINA_FALSE if an error - * occurred, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_hash_add(Eina_Hash * hash, const void *key, const void *data) -{ - unsigned int key_length; - int key_hash; - - EINA_MAGIC_CHECK_HASH(hash); - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); - - key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; - key_hash = hash->key_hash_cb(key, key_length); - - return eina_hash_add_alloc_by_hash(hash, key, key_length, - key_length, key_hash, data); -} - -/** - * @brief Add an entry to the given hash table without duplicating the string key. - * - * @param hash The given hash table. Can be @c NULL. - * @param key A unique key. Can be @c NULL. - * @param data Data to associate with the string given by @p key. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function adds @p key to @p hash. @p hash, @p key and @p data - * can be @c NULL, in that case #EINA_FALSE is returned. @p key is - * expected to be unique within the hash table. Key uniqueness varies - * depending on the type of @p hash: a stringshared @ref Eina_Hash - * need only have unique pointers for keys, but the strings in the - * pointers may be identical. All other hash types require the strings - * themselves to be unique. Failure to use sufficient uniqueness will - * result in unexpected results when inserting data pointers accessed - * with eina_hash_find(), and removed with eina_hash_del(). This - * function does not make a copy of @p key, so it must be a string - * constant or stored elsewhere ( in the object being added). Key - * strings are case sensitive. If an error occurs, eina_error_get() - * should be used to determine if an allocation error occurred during - * this function. This function returns #EINA_FALSE if an error - * occurred, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_hash_direct_add(Eina_Hash * hash, const void *key, const void *data) -{ - int key_length; - int key_hash; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); - EINA_MAGIC_CHECK_HASH(hash); - - key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; - key_hash = hash->key_hash_cb(key, key_length); - - return eina_hash_add_alloc_by_hash(hash, key, key_length, 0, - key_hash, data); -} - -/** - * @brief Remove the entry identified by a key and a key hash from the given hash table. - * - * @param hash The given hash table. - * @param key The key. - * @param key_length The length of the key. - * @param key_hash The hash that always match the key. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function removes the entry identified by @p key and - * @p key_hash from @p hash. If a free function was given to the - * callback on creation, it will be called for the data being - * deleted. Do not forget to count '\\0' for string when setting the - * value of @p key_length. If @p hash or @p key are @c NULL, the - * functions returns immediately #EINA_FALSE. This function returns - * #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * @note if you don't have the key_hash, use eina_hash_del_by_key() instead. - * @note if you don't have the key, use eina_hash_del_by_data() instead. - */ -EAPI Eina_Bool -eina_hash_del_by_key_hash(Eina_Hash * hash, - const void *key, int key_length, int key_hash) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); - - return _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, - NULL); -} - -/** - * @brief Remove the entry identified by a key from the given hash table. - * - * This version will calculate key length and hash by using functions - * provided to hash creation function. - * - * @param hash The given hash table. - * @param key The key. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function removes the entry identified by @p key from @p - * hash. The key length and hash will be calculated automatically by - * using functiond provided to has creation function. If a free - * function was given to the callback on creation, it will be called - * for the data being deleted. If @p hash or @p key are @c NULL, the - * functions returns immediately #EINA_FALSE. This function returns - * #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * @note if you already have the key_hash, use eina_hash_del_by_key_hash() instead. - * @note if you don't have the key, use eina_hash_del_by_data() instead. - */ -EAPI Eina_Bool eina_hash_del_by_key(Eina_Hash * hash, const void *key) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); - - return _eina_hash_del_by_key(hash, key, NULL); -} - -/** - * @brief Remove the entry identified by a data from the given hash table. - * - * This version is slow since there is no quick access to nodes based on data. - * - * @param hash The given hash table. - * @param data The data value to search and remove. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * thing goes fine. - * - * This function removes the entry identified by @p data from @p - * hash. If a free function was given to the callback on creation, it - * will be called for the data being deleted. If @p hash or @p data - * are @c NULL, the functions returns immediately #EINA_FALSE. This - * function returns #EINA_FALSE if an error occurred, #EINA_TRUE - * otherwise. - * - * @note if you already have the key, use eina_hash_del_by_key() or eina_hash_del_by_key_hash() instead. - */ -EAPI Eina_Bool eina_hash_del_by_data(Eina_Hash * hash, const void *data) -{ - Eina_Hash_Element *hash_element; - Eina_Hash_Head *hash_head; - int key_hash; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); - EINA_MAGIC_CHECK_HASH(hash); - - hash_element = - _eina_hash_find_by_data(hash, data, &key_hash, &hash_head); - if (!hash_element) - goto error; - - if (hash_element->tuple.data != data) - goto error; - - return _eina_hash_del_by_hash_el(hash, hash_element, hash_head, - key_hash); - - error: - return EINA_FALSE; -} - -/** - * @brief Remove the entry identified by a key and a key hash or a - * 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. - * @param key_length The length of the key. - * @param key_hash The hash that always match the key. - * @param data The data pointer to remove if the key is @c NULL. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function removes the entry identified by @p key and - * @p key_hash, or @p data, from @p hash. If a free function was given to - * the callback on creation, it will be called for the data being - * deleted. If @p hash is @c NULL, the functions returns immediately - * #EINA_FALSE. If @p key is @c NULL, then @p key_hash and @p key_hash - * are ignored and @p data is used to find a match to remove, - * otherwise @p key and @p key_hash are used and @p data is not - * required and can be @c NULL. Do not forget to count '\\0' for - * string when setting the value of @p key_length. This function - * returns #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * @note if you know you already have the key, use eina_hash_del_by_key_hash(), - * if you know you don't have the key, use eina_hash_del_by_data() - * directly. - */ -EAPI Eina_Bool -eina_hash_del_by_hash(Eina_Hash * hash, - const void *key, - int key_length, int key_hash, const void *data) -{ - Eina_Bool ret; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_MAGIC_CHECK_HASH(hash); - - if (key) - ret = - _eina_hash_del_by_key_hash(hash, key, key_length, - key_hash, data); - else - ret = eina_hash_del_by_data(hash, data); - - return ret; -} - -/** - * @brief Remove the entry identified by a key or a data from the given - * hash table. - * - * @param hash The given hash table. - * @param key The key. - * @param data The data pointer to remove if the key is @c NULL. - * @return #EINA_FALSE if an error occurred, #EINA_TRUE otherwise. - * - * This function removes the entry identified by @p key or @p data - * from @p hash. If a free function was given to the - * callback on creation, it will be called for the data being - * deleted. If @p hash is @c NULL, the functions returns immediately - * #EINA_FALSE. If @p key is @c NULL, then @p data is used to find the a - * match to remove, otherwise @p key is used and @p data is not - * required and can be @c NULL. This function returns #EINA_FALSE if - * an error occurred, #EINA_TRUE otherwise. - * - * @note if you know you already have the key, use - * eina_hash_del_by_key() or eina_hash_del_by_key_hash(). If you - * know you don't have the key, use eina_hash_del_by_data() - * directly. - */ -EAPI Eina_Bool -eina_hash_del(Eina_Hash * hash, const void *key, const void *data) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_MAGIC_CHECK_HASH(hash); - - if (!key) - return eina_hash_del_by_data(hash, data); - - return _eina_hash_del_by_key(hash, key, data); -} - -/** - * @brief Retrieve a specific entry in the given hash table. - * - * @param hash The given hash table. - * @param key The key of the entry to find. - * @param key_length The length of the key. - * @param key_hash The hash that always match the key - * @return The data pointer for the stored entry on success, @c NULL - * otherwise. - * - * This function retrieves the entry associated to @p key of length - * @p key_length in @p hash. @p key_hash is the hash that always match - * @p key. It is ignored if @p key is @c NULL. Do not forget to count - * '\\0' for string when setting the value of @p key_length. If - * @p hash is @c NULL, this function returns immediately @c NULL. This - * function returns the data pointer on success, @c NULL otherwise. - */ -EAPI void *eina_hash_find_by_hash(const Eina_Hash * hash, - const void *key, - int key_length, int key_hash) -{ - Eina_Hash_Head *hash_head; - Eina_Hash_Element *hash_element; - Eina_Hash_Tuple tuple; - - if (!hash) - return NULL; - - EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - tuple.key = key; - tuple.key_length = key_length; - tuple.data = NULL; - - hash_element = - _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); - if (hash_element) - return hash_element->tuple.data; - - return NULL; -} - -/** - * @brief Retrieve a specific entry in the given hash table. - * - * @param hash The given hash table. - * @param key The key of the entry to find. - * @return The data pointer for the stored entry on success, @c NULL - * otherwise. - * - * This function retrieves the entry associated to @p key in - * @p hash. If @p hash is @c NULL, this function returns immediately - * @c NULL. This function returns the data pointer on success, @c NULL - * otherwise. - */ -EAPI void *eina_hash_find(const Eina_Hash * hash, const void *key) -{ - int key_length; - int hash_num; - - if (!hash) - return NULL; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; - hash_num = hash->key_hash_cb(key, key_length); - - return eina_hash_find_by_hash(hash, key, key_length, hash_num); -} - -/** - * @brief Modify the entry pointer at the specified key and returns - * the old entry. - * - * @param hash The given hash table. - * @param key The key of the entry to modify. - * @param key_length Should be the length of @p key (don't forget to count '\\0' for string). - * @param key_hash The hash that always match the key. Ignored if @p key is @c NULL. - * @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. - */ -EAPI void *eina_hash_modify_by_hash(Eina_Hash * hash, - const void *key, - int key_length, - int key_hash, const void *data) -{ - Eina_Hash_Head *hash_head; - Eina_Hash_Element *hash_element; - void *old_data = NULL; - Eina_Hash_Tuple tuple; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - tuple.key = key; - tuple.key_length = key_length; - tuple.data = NULL; - - hash_element = - _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); - if (hash_element) { - old_data = hash_element->tuple.data; - hash_element->tuple.data = (void *) data; - } - - return old_data; -} - -/** - * @brief Modify the entry pointer at the specified key and return the - * old entry or add the entry if not found. - * - * @param hash The given hash table. - * @param key The key of the entry to modify. - * @param data The data to replace the old entry - * @return The data pointer for the old stored entry, or @c NULL - * otherwise. - * - * This function modifies the data of @p key with @p data in @p - * hash. If no entry is found, @p data is added to @p hash with the - * key @p key. On success this function returns the old entry, - * otherwise it returns @c NULL. To check for errors, use - * eina_error_get(). - */ -EAPI void *eina_hash_set(Eina_Hash * hash, const void *key, - const void *data) -{ - Eina_Hash_Tuple tuple; - Eina_Hash_Head *hash_head; - Eina_Hash_Element *hash_element; - int key_length; - int key_hash; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; - key_hash = hash->key_hash_cb(key, key_length); - - tuple.key = key; - tuple.key_length = key_length; - tuple.data = NULL; - - hash_element = - _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); - if (hash_element) { - void *old_data = NULL; - - old_data = hash_element->tuple.data; - hash_element->tuple.data = (void *) data; - return old_data; - } - - eina_hash_add_alloc_by_hash(hash, - key, - key_length, - key_length, key_hash, data); - return NULL; -} - -/** - * @brief Modify the entry pointer at the specified key and return the old entry. - * @param hash The given hash table. - * @param key The key of the entry to modify. - * @param data The data to replace the old entry. - * @return The data pointer for the old stored entry on success, or - * @c NULL otherwise. - * - * This function modifies the data of @p key with @p data in @p - * hash. If no entry is found, nothing is added to @p hash. On success - * this function returns the old entry, otherwise it returns @c NULL. - */ -EAPI void *eina_hash_modify(Eina_Hash * hash, const void *key, - const void *data) -{ - int key_length; - int hash_num; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; - hash_num = hash->key_hash_cb(key, key_length); - - return eina_hash_modify_by_hash(hash, key, key_length, hash_num, - data); -} - -/** - * @brief Change the key associated with a data without triggering the - * free callback. - * - * @param hash The given hash table. - * @param old_key The current key associated with the data - * @param new_key The new key to associate data with - * @return EINA_FALSE in any case but success, EINA_TRUE on success. - * - * This function allows for the move of data from one key to another, - * but does not call the Eina_Free_Cb associated with the hash table - * when destroying the old key. - */ -EAPI Eina_Bool -eina_hash_move(Eina_Hash * hash, const void *old_key, const void *new_key) -{ - Eina_Free_Cb hash_free_cb; - const void *data; - Eina_Bool result = EINA_FALSE; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(old_key, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(new_key, EINA_FALSE); - EINA_MAGIC_CHECK_HASH(hash); - - data = eina_hash_find(hash, old_key); - if (!data) - goto error; - - hash_free_cb = hash->data_free_cb; - hash->data_free_cb = NULL; - - eina_hash_del(hash, old_key, data); - result = eina_hash_add(hash, new_key, data); - - hash->data_free_cb = hash_free_cb; - - error: - return result; -} - -/*============================================================================* -* Iterator * -*============================================================================*/ - -/** - * @brief 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 @b not modify the - * hash table contents if it returns 1. @b If the hash table contents are - * modified by this function or the function wishes to stop processing it must - * return 0, otherwise return 1 to keep processing. - * - * Example: - * @code - * extern Eina_Hash *hash; - * - * Eina_Bool hash_fn(const Eina_Hash *hash, const void *key, void *data, void *fdata) - * { - * printf("Func data: %s, Hash entry: %s / %p\n", fdata, (const char *)key, data); - * return 1; - * } - * - * int main(int argc, char **argv) - * { - * char *hash_fn_data; - * - * hash_fn_data = strdup("Hello World"); - * eina_hash_foreach(hash, hash_fn, hash_fn_data); - * free(hash_fn_data); - * } - * @endcode - */ -EAPI void -eina_hash_foreach(const Eina_Hash * hash, - Eina_Hash_Foreach func, const void *fdata) -{ - Eina_Iterator *it; - Eina_Hash_Foreach_Data foreach; - - EINA_MAGIC_CHECK_HASH(hash); - EINA_SAFETY_ON_NULL_RETURN(hash); - EINA_SAFETY_ON_NULL_RETURN(func); - - foreach.cb = func; - foreach.fdata = fdata; - - it = eina_hash_iterator_tuple_new(hash); - if (!it) - return; - eina_iterator_foreach(it, EINA_EACH_CB(_eina_foreach_cb), - &foreach); - - eina_iterator_free(it); -} - -/** - * @brief Returned a new iterator associated to hash data. - * - * @param hash The hash. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to - * @p hash. If @p hash is not populated, this function still returns a - * valid iterator that will always return false on - * eina_iterator_next(), thus keeping API sane. - * - * If the memory can not be allocated, @c NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the hash structure changes then the iterator becomes - * invalid. That is, if you add or remove items this iterator behavior - * is undefined and your program may crash. - */ -EAPI Eina_Iterator *eina_hash_iterator_data_new(const Eina_Hash * hash) -{ - Eina_Iterator_Hash *it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_Hash)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - it->hash = hash; - it->get_content = - FUNC_ITERATOR_GET_CONTENT - (_eina_hash_iterator_data_get_content); - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(_eina_hash_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free); - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR); - - return &it->iterator; -} - -/** - * @brief Returned a new iterator associated to hash keys. - * - * @param hash The hash. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * hash. If @p hash is not populated, this function still returns a - * valid iterator that will always return false on - * eina_iterator_next(), thus keeping API sane. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the hash structure changes then the iterator becomes - * invalid! That is, if you add or remove items this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_hash_iterator_key_new(const Eina_Hash * hash) -{ - Eina_Iterator_Hash *it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_Hash)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - it->hash = hash; - it->get_content = - FUNC_ITERATOR_GET_CONTENT(_eina_hash_iterator_key_get_content); - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(_eina_hash_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free); - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR); - - return &it->iterator; -} - -/** - * @brief Returned a new iterator associated to hash keys and data. - * - * @param hash The hash. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * hash. If @p hash is not populated, this function still returns a - * valid iterator that will always return false on - * eina_iterator_next(), thus keeping API sane. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @note iterator data will provide values as Eina_Hash_Tuple that should not - * be modified! - * - * @warning if the hash structure changes then the iterator becomes - * invalid! That is, if you add or remove items this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_hash_iterator_tuple_new(const Eina_Hash * hash) -{ - Eina_Iterator_Hash *it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); - EINA_MAGIC_CHECK_HASH(hash); - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_Hash)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - it->hash = hash; - it->get_content = - FUNC_ITERATOR_GET_CONTENT - (_eina_hash_iterator_tuple_get_content); - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(_eina_hash_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free); - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR); - - return &it->iterator; -} - -/* Common hash functions */ - -/* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html) - used by WebCore (http://webkit.org/blog/8/hashtables-part-2/) */ -EAPI int eina_hash_superfast(const char *key, int len) -{ - unsigned hash = len; - int tmp; - int rem; - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (; len > 0; len--) { - hash += get16bits(key); - tmp = (get16bits(key + 2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - key += 2 * sizeof(uint16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) { - case 3: - hash += get16bits(key); - hash ^= hash << 16; - hash ^= key[sizeof(uint16_t)] << 18; - hash += hash >> 11; - break; - - case 2: - hash += get16bits(key); - hash ^= hash << 11; - hash += hash >> 17; - break; - - case 1: - hash += *key; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; -} - -/** - * @} - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_inlist.c b/tests/suite/ecore/src/lib/eina_inlist.c deleted file mode 100644 index f26c2548b5..0000000000 --- a/tests/suite/ecore/src/lib/eina_inlist.c +++ /dev/null @@ -1,667 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Vincent Torri - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <assert.h> - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_error.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_inlist.h" - -/* FIXME: TODO please, refactor this :) */ - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -typedef struct _Eina_Iterator_Inlist Eina_Iterator_Inlist; -typedef struct _Eina_Accessor_Inlist Eina_Accessor_Inlist; - -struct _Eina_Iterator_Inlist { - Eina_Iterator iterator; - const Eina_Inlist *head; - const Eina_Inlist *current; -}; - -struct _Eina_Accessor_Inlist { - Eina_Accessor accessor; - - const Eina_Inlist *head; - const Eina_Inlist *current; - - unsigned int index; -}; - -static Eina_Bool -eina_inlist_iterator_next(Eina_Iterator_Inlist * it, void **data) -{ - if (!it->current) - return EINA_FALSE; - - if (data) - *data = (void *) it->current; - - it->current = it->current->next; - - return EINA_TRUE; -} - -static Eina_Inlist *eina_inlist_iterator_get_container(Eina_Iterator_Inlist - * it) -{ - return (Eina_Inlist *) it->head; -} - -static void eina_inlist_iterator_free(Eina_Iterator_Inlist * it) -{ - free(it); -} - -static Eina_Bool -eina_inlist_accessor_get_at(Eina_Accessor_Inlist * it, - unsigned int idx, void **data) -{ - const Eina_Inlist *over; - unsigned int middle; - unsigned int i; - - if (it->index == idx) - over = it->current; - else if (idx > it->index) - /* Looking after current. */ - for (i = it->index, over = it->current; - i < idx && over; ++i, over = over->next); - else { - middle = it->index >> 1; - - if (idx > middle) - /* Looking backward from current. */ - for (i = it->index, over = it->current; - i > idx && over; --i, over = over->prev); - else - /* Looking from the start. */ - for (i = 0, over = it->head; - i < idx && over; ++i, over = over->next); - } - - if (!over) - return EINA_FALSE; - - it->current = over; - it->index = idx; - - if (data) - *data = (void *) over; - - return EINA_TRUE; -} - -static Eina_Inlist *eina_inlist_accessor_get_container(Eina_Accessor_Inlist - * it) -{ - return (Eina_Inlist *) it->head; -} - -static void eina_inlist_accessor_free(Eina_Accessor_Inlist * it) -{ - free(it); -} - -/** - * @endcond - */ - - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Inline_List_Group Inline List - * - * @brief These functions provide inline list management. - * - * Inline lists mean its nodes pointers are part of same memory as - * data. This has the benefit of framenting memory less and avoiding - * @c node->data indirection, but has the drawback of elements only - * being able to be part of one single inlist at same time. But it is - * possible to have inlist nodes to be part of regular lists created - * with eina_list_append() or eina_list_prepend(). - * - * Inline lists have its purposes, but if you don't know them go with - * regular lists instead. - * - * @code - * #include <Eina.h> - * #include <stdio.h> - * - * int - * main(void) - * { - * struct my_struct { - * EINA_INLIST; - * int a, b; - * } *d, *cur; - * Eina_Inlist *list, *itr; - * - * eina_init(); - * - * d = malloc(sizeof(*d)); - * d->a = 1; - * d->b = 10; - * list = eina_inlist_append(NULL, EINA_INLIST_GET(d)); - * - * d = malloc(sizeof(*d)); - * d->a = 2; - * d->b = 20; - * list = eina_inlist_append(list, EINA_INLIST_GET(d)); - * - * d = malloc(sizeof(*d)); - * d->a = 3; - * d->b = 30; - * list = eina_inlist_prepend(list, EINA_INLIST_GET(d)); - * - * printf("list=%p\n", list); - * EINA_INLIST_FOREACH(list, cur) - * printf("\ta=%d, b=%d\n", cur->a, cur->b); - * - * list = eina_inlist_remove(list, EINA_INLIST_GET(d)); - * free(d); - * printf("list=%p\n", list); - * for (itr = list; itr != NULL; itr = itr->next) - * { - * cur = EINA_INLIST_CONTAINER_GET(itr, struct my_struct); - * printf("\ta=%d, b=%d\n", cur->a, cur->b); - * } - * - * while (list) - * { - * Eina_Inlist *aux = list; - * list = eina_inlist_remove(list, list); - * free(aux); - * } - * - * eina_shutdown(); - * - * return 0; - * } - * @endcode - * - * @{ - */ - -/** - * Add a new node to end of list. - * - * @note this code is meant to be fast, appends are O(1) and do not - * walk @a list anyhow. - * - * @note @a new_l is considered to be in no list. If it was in another - * list before, please eina_inlist_remove() it before adding. No - * check of @a new_l prev and next pointers is done, so it' safe - * to have them uninitialized. - * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. - * - * @return the new list head. Use it and not given @a list anymore. - */ -EAPI Eina_Inlist *eina_inlist_append(Eina_Inlist * list, - Eina_Inlist * new_l) -{ - Eina_Inlist *l; - - EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); - - 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; -} - -/** - * Add a new node to beginning of list. - * - * @note this code is meant to be fast, prepends are O(1) and do not - * walk @a list anyhow. - * - * @note @a new_l is considered to be in no list. If it was in another - * list before, please eina_inlist_remove() it before adding. No - * check of @a new_l prev and next pointers is done, so it' safe - * to have them uninitialized. - * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. - * - * @return the new list head. Use it and not given @a list anymore. - */ -EAPI Eina_Inlist *eina_inlist_prepend(Eina_Inlist * list, - Eina_Inlist * new_l) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); - - 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; -} - -/** - * Add a new node after the given relative item in list. - * - * @note this code is meant to be fast, appends are O(1) and do not - * walk @a list anyhow. - * - * @note @a new_l is considered to be in no list. If it was in another - * list before, please eina_inlist_remove() it before adding. No - * check of @a new_l prev and next pointers is done, so it' safe - * to have them uninitialized. - * - * @note @a relative is considered to be inside @a list, no checks are - * done to confirm that and giving nodes from different lists - * will lead to problems. Giving NULL @a relative is the same as - * eina_list_append(). - * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. - * @param relative reference node, @a new_l will be added after it. - * - * @return the new list head. Use it and not given @a list anymore. - */ -EAPI Eina_Inlist *eina_inlist_append_relative(Eina_Inlist * list, - Eina_Inlist * new_l, - Eina_Inlist * relative) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); - - if (relative) { - if (relative->next) { - new_l->next = relative->next; - relative->next->prev = new_l; - } else - new_l->next = NULL; - - relative->next = new_l; - new_l->prev = relative; - if (!new_l->next) - list->last = new_l; - - return list; - } - - return eina_inlist_append(list, new_l); -} - -/** - * Add a new node before the given relative item in list. - * - * @note this code is meant to be fast, prepends are O(1) and do not - * walk @a list anyhow. - * - * @note @a new_l is considered to be in no list. If it was in another - * list before, please eina_inlist_remove() it before adding. No - * check of @a new_l prev and next pointers is done, so it' safe - * to have them uninitialized. - * - * @note @a relative is considered to be inside @a list, no checks are - * done to confirm that and giving nodes from different lists - * will lead to problems. Giving NULL @a relative is the same as - * eina_list_prepend(). - * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. - * @param relative reference node, @a new_l will be added before it. - * - * @return the new list head. Use it and not given @a list anymore. - */ -EAPI Eina_Inlist *eina_inlist_prepend_relative(Eina_Inlist * list, - Eina_Inlist * new_l, - Eina_Inlist * relative) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); - - 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; - /* new_l->next could not be NULL, as it was set to 'relative' */ - assert(new_l->next); - return list; - } else { - /* new_l->next could not be NULL, as it was set to 'relative' */ - assert(new_l->next); - - new_l->last = list->last; - list->last = NULL; - return new_l; - } - } - - return eina_inlist_prepend(list, new_l); -} - -/** - * Remove node from list. - * - * @note this code is meant to be fast, removals are O(1) and do not - * walk @a list anyhow. - * - * @note @a item is considered to be inside @a list, no checks are - * done to confirm that and giving nodes from different lists - * will lead to problems, specially if @a item is the head since - * it will be different from @a list and the wrong new head will - * be returned. - * - * @param list existing list head, must not be NULL. - * @param item existing list node, must not be NULL. - * - * @return the new list head. Use it and not given @a list anymore. - */ -EAPI Eina_Inlist *eina_inlist_remove(Eina_Inlist * list, - Eina_Inlist * item) -{ - Eina_Inlist *return_l; - - /* checkme */ - EINA_SAFETY_ON_NULL_RETURN_VAL(list, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(item, list); - EINA_SAFETY_ON_TRUE_RETURN_VAL - ((item != list) && (!item->prev) && (!item->next), 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; -} - -/** - * Move existing node to beginning of list. - * - * @note this code is meant to be fast, promotion is O(1) and do not - * walk @a list anyhow. - * - * @note @a item is considered to be inside @a list, no checks are - * done to confirm that and giving nodes from different lists - * will lead to problems. - * - * @param list existing list head or NULL to create a new list. - * @param item list node to move to beginning (head), must not be NULL. - * - * @return the new list head. Use it and not given @a list anymore. - */ -EAPI Eina_Inlist *eina_inlist_promote(Eina_Inlist * list, - Eina_Inlist * item) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(list, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(item, list); - - if (item == list) - return list; - - if (item->next) - item->next->prev = item->prev; - - item->prev->next = item->next; - - if (list->last == item) - list->last = item->prev; - - item->next = list; - item->prev = NULL; - item->last = list->last; - - list->prev = item; - list->last = NULL; - - return item; -} - -/** - * Move existing node to end of list. - * - * @note this code is meant to be fast, demoting is O(1) and do not - * walk @a list anyhow. - * - * @note @a item is considered to be inside @a list, no checks are - * done to confirm that and giving nodes from different lists - * will lead to problems. - * - * @param list existing list head or NULL to create a new list. - * @param item list node to move to end (tail), must not be NULL. - * - * @return the new list head. Use it and not given @a list anymore. - */ -EAPI Eina_Inlist *eina_inlist_demote(Eina_Inlist * list, - Eina_Inlist * item) -{ - Eina_Inlist *l; - - EINA_SAFETY_ON_NULL_RETURN_VAL(list, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(item, list); - - if (list->last == item) - return list; - - if (!list->last) { - for (l = list; l->next; l = l->next); - list->last = l; - } - - l = list; - if (item->prev) - item->prev->next = item->next; - else - l = item->next; - - item->next->prev = item->prev; - - list->last->next = item; - item->prev = list->last; - item->next = NULL; - - l->last = item; - return l; -} - -/** - * Find given node in list, returns itself if found, NULL if not. - * - * @warning this is an expensive call and have O(n) cost, possibly - * walking the whole list. - * - * @param list existing list to search @a item in, must not be NULL. - * @param item what to search for, must not be NULL. - * - * @return @a item if found, NULL if not. - */ -EAPI Eina_Inlist *eina_inlist_find(Eina_Inlist * list, Eina_Inlist * item) -{ - Eina_Inlist *l; - - for (l = list; l; l = l->next) { - if (l == item) - return item; - } - return NULL; -} - -/** - * @brief Get the count of the number of items in a list. - * - * @param list The list whose count to return. - * @return The number of members in the list. - * - * This function returns how many members @p list contains. If the - * list is @c NULL, 0 is returned. - * - * @warning This is an order-N operation and so the time will depend - * on the number of elements on the list, that is, it might become - * slow for big lists! - */ -EAPI unsigned int eina_inlist_count(const Eina_Inlist * list) -{ - const Eina_Inlist *l; - unsigned int i = 0; - - for (l = list; l; l = l->next) - i++; - - return i; -} - -/** - * @brief Returned a new iterator associated to a list. - * - * @param list The list. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * list. If @p list is @c NULL or the count member of @p list is less - * or equal than 0, this function still returns a valid iterator that - * will always return false on eina_iterator_next(), thus keeping API - * sane. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the list structure changes then the iterator becomes - * invalid! That is, if you add or remove nodes this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_inlist_iterator_new(const Eina_Inlist * list) -{ - Eina_Iterator_Inlist *it; - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_Inlist)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - it->head = list; - it->current = list; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(eina_inlist_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER - (eina_inlist_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(eina_inlist_iterator_free); - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - return &it->iterator; -} - -/** - * @brief Returned a new accessor associated to a list. - * - * @param list The list. - * @return A new accessor. - * - * This function returns a newly allocated accessor associated to - * @p list. If @p list is @c NULL or the count member of @p list is - * less or equal than 0, this function returns NULL. If the memory can - * not be allocated, NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is - * set. Otherwise, a valid accessor is returned. - */ -EAPI Eina_Accessor *eina_inlist_accessor_new(const Eina_Inlist * list) -{ - Eina_Accessor_Inlist *ac; - - eina_error_set(0); - ac = calloc(1, sizeof(Eina_Accessor_Inlist)); - if (!ac) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - ac->head = list; - ac->current = list; - ac->index = 0; - - ac->accessor.version = EINA_ACCESSOR_VERSION; - ac->accessor.get_at = - FUNC_ACCESSOR_GET_AT(eina_inlist_accessor_get_at); - ac->accessor.get_container = - FUNC_ACCESSOR_GET_CONTAINER - (eina_inlist_accessor_get_container); - ac->accessor.free = FUNC_ACCESSOR_FREE(eina_inlist_accessor_free); - - EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); - - return &ac->accessor; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_iterator.c b/tests/suite/ecore/src/lib/eina_iterator.c deleted file mode 100644 index 29bc4ebc2b..0000000000 --- a/tests/suite/ecore/src/lib/eina_iterator.c +++ /dev/null @@ -1,254 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> - -#include "eina_config.h" -#include "eina_private.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_iterator.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static const char EINA_MAGIC_ITERATOR_STR[] = "Eina Iterator"; - -#define EINA_MAGIC_CHECK_ITERATOR(d) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ITERATOR)) { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_ITERATOR); } \ - } while(0) - -/** - * @endcond - */ - - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the iterator module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the iterator module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_iterator_init(void) -{ - return eina_magic_string_set(EINA_MAGIC_ITERATOR, - EINA_MAGIC_ITERATOR_STR); -} - -/** - * @internal - * @brief Shut down the iterator module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the iterator module set up by - * eina_iterator_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_iterator_shutdown(void) -{ - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Iterator_Group Iterator Functions - * - * @brief These functions manage iterators on containers. - * - * These functions allow to access elements of a container in a - * generic way, without knowing which container is used (a bit like - * iterators in the C++ STL). Iterators only allows sequential access - * (that is, from an element to the next one). For random access, see - * @ref Eina_Accessor_Group. - * - * An iterator is created from container data types, so no creation - * function is available here. An iterator is deleted with - * eina_iterator_free(). To get the data and iterate, use - * eina_iterator_next(). To call a function on all the elements of a - * container, use eina_iterator_foreach(). - * - * @{ - */ - -/** - * @brief Free an iterator. - * - * @param iterator The iterator to free. - * - * This function frees @p iterator if it is not @c NULL; - */ -EAPI void eina_iterator_free(Eina_Iterator * iterator) -{ - EINA_MAGIC_CHECK_ITERATOR(iterator); - EINA_SAFETY_ON_NULL_RETURN(iterator); - EINA_SAFETY_ON_NULL_RETURN(iterator->free); - iterator->free(iterator); -} - -/** - * @brief Return the container of an iterator. - * - * @param iterator The iterator. - * @return The container which created the iterator. - * - * This function returns the container which created @p iterator. If - * @p iterator is @c NULL, this function returns @c NULL. - */ -EAPI void *eina_iterator_container_get(Eina_Iterator * iterator) -{ - EINA_MAGIC_CHECK_ITERATOR(iterator); - EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->get_container, NULL); - return iterator->get_container(iterator); -} - -/** - * @brief Return the value of the current element and go to the next one. - * - * @param iterator The iterator. - * @param data The data of the element. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function returns the value of the current element pointed by - * @p iterator in @p data, then goes to the next element. If @p - * iterator is @c NULL or if a problem occurred, #EINA_FALSE is - * returned, otherwise #EINA_TRUE is returned. - */ -EAPI Eina_Bool eina_iterator_next(Eina_Iterator * iterator, void **data) -{ - if (!iterator) - return EINA_FALSE; - - EINA_MAGIC_CHECK_ITERATOR(iterator); - EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->next, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); - return iterator->next(iterator, data); -} - -/** - * @brief Iterate over the container and execute a callback on each element. - * - * @param iterator The iterator. - * @param cb The callback called on each iteration. - * @param fdata The data passed to the callback. - * - * This function iterates over the elements pointed by @p iterator, - * beginning from the current element. For Each element, the callback - * @p cb is called with the data @p fdata. If @p iterator is @c NULL, - * the function returns immediately. Also, if @p cb returns @c - * EINA_FALSE, the iteration stops at that point. - */ -EAPI void -eina_iterator_foreach(Eina_Iterator * iterator, - Eina_Each_Cb cb, const void *fdata) -{ - const void *container; - void *data; - - EINA_MAGIC_CHECK_ITERATOR(iterator); - EINA_SAFETY_ON_NULL_RETURN(iterator); - EINA_SAFETY_ON_NULL_RETURN(iterator->get_container); - EINA_SAFETY_ON_NULL_RETURN(iterator->next); - EINA_SAFETY_ON_NULL_RETURN(cb); - - if (!eina_iterator_lock(iterator)) - return; - - container = iterator->get_container(iterator); - while (iterator->next(iterator, &data) == EINA_TRUE) { - if (cb(container, data, (void *) fdata) != EINA_TRUE) - goto on_exit; - } - - on_exit: - (void) eina_iterator_unlock(iterator); -} - -/** - * @brief Lock the container of the iterator. - * - * @param iterator The iterator. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * If the container of the @p iterator permit it, it will be locked. - * If @p iterator is @c NULL or if a problem occurred, #EINA_FALSE is - * returned, otherwise #EINA_TRUE is returned. If the container - * is not lockable, it will return EINA_TRUE. - */ -EAPI Eina_Bool eina_iterator_lock(Eina_Iterator * iterator) -{ - EINA_MAGIC_CHECK_ITERATOR(iterator); - EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE); - - if (iterator->lock) - return iterator->lock(iterator); - return EINA_TRUE; -} - -/** - * @brief Unlock the container of the iterator. - * - * @param iterator The iterator. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * If the container of the @p iterator permit it and was previously - * locked, it will be unlocked. If @p iterator is @c NULL or if a - * problem occurred, #EINA_FALSE is returned, otherwise #EINA_TRUE - * is returned. If the container is not lockable, it will return - * EINA_TRUE. - */ -EAPI Eina_Bool eina_iterator_unlock(Eina_Iterator * iterator) -{ - EINA_MAGIC_CHECK_ITERATOR(iterator); - EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE); - - if (iterator->unlock) - return iterator->unlock(iterator); - return EINA_TRUE; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_lalloc.c b/tests/suite/ecore/src/lib/eina_lalloc.c deleted file mode 100644 index e118a62229..0000000000 --- a/tests/suite/ecore/src/lib/eina_lalloc.c +++ /dev/null @@ -1,148 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> - -#include "eina_config.h" -#include "eina_private.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_lalloc.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -struct _Eina_Lalloc { - void *data; - int num_allocated; - int num_elements; - int acc; - Eina_Lalloc_Alloc alloc_cb; - Eina_Lalloc_Free free_cb; -}; - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Lalloc_Group Lazy allocator - * - * @{ - */ - -EAPI Eina_Lalloc *eina_lalloc_new(void *data, - Eina_Lalloc_Alloc alloc_cb, - Eina_Lalloc_Free free_cb, int num_init) -{ - Eina_Lalloc *a; - - EINA_SAFETY_ON_NULL_RETURN_VAL(alloc_cb, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(free_cb, NULL); - - a = calloc(1, sizeof(Eina_Lalloc)); - a->data = data; - a->alloc_cb = alloc_cb; - a->free_cb = free_cb; - if (num_init > 0) { - a->num_allocated = num_init; - a->alloc_cb(a->data, a->num_allocated); - } - - return a; -} - -EAPI void eina_lalloc_free(Eina_Lalloc * a) -{ - EINA_SAFETY_ON_NULL_RETURN(a); - EINA_SAFETY_ON_NULL_RETURN(a->free_cb); - a->free_cb(a->data); - free(a); -} - -EAPI Eina_Bool eina_lalloc_element_add(Eina_Lalloc * a) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(a, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(a->alloc_cb, EINA_FALSE); - - if (a->num_elements == a->num_allocated) { - if (a->alloc_cb(a->data, (1 << a->acc)) == EINA_TRUE) { - a->num_allocated = (1 << a->acc); - a->acc++; - } else - return EINA_FALSE; - } - - a->num_elements++; - - return EINA_TRUE; -} - -EAPI Eina_Bool eina_lalloc_elements_add(Eina_Lalloc * a, int num) -{ - int tmp; - - EINA_SAFETY_ON_NULL_RETURN_VAL(a, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(a->alloc_cb, EINA_FALSE); - - tmp = a->num_elements + num; - if (tmp > a->num_allocated) { - int allocated; - int acc; - - allocated = a->num_allocated; - acc = a->acc; - - while (tmp > allocated) { - allocated = (1 << acc); - acc++; - } - - if (a->alloc_cb(a->data, allocated) == EINA_TRUE) { - a->num_allocated = allocated; - a->acc = acc; - } else - return EINA_FALSE; - } - - a->num_elements += num; - - return EINA_TRUE; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_list.c b/tests/suite/ecore/src/lib/eina_list.c deleted file mode 100644 index 0b0c12d5c8..0000000000 --- a/tests/suite/ecore/src/lib/eina_list.c +++ /dev/null @@ -1,2101 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Gustavo Sverzut Barbieri, Tilman Sauerbeck, - * Vincent Torri, Cedric Bail, Jorge Luis Zapata Muga, - * Corey Donohoe, Arnaud de Turckheim, Alexandre Becoulet - * - * 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 <https://www.gnu.org/licenses/>. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (C) 2004 ncn - * Copyright (C) 2006 Sebastian Dransfeld - * Copyright (C) 2007 Christopher Michael - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies of the Software and its Copyright notices. In addition publicly - * documented acknowledgment must be given that this software has been used if no - * source code of this software is made available publicly. This includes - * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing - * documents or any documentation provided with any product containing this - * software. This License does not apply to any software that links to the - * libraries provided by this software (statically or dynamically), but only to - * the software provided. - - * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice - * and it's intent. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * @page tutorial_list_page List Tutorial - * - * to be written... - * - */ - -#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_config.h" -#include "eina_private.h" -#include "eina_error.h" -#include "eina_log.h" -#include "eina_mempool.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_list.h" - - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static const char EINA_MAGIC_LIST_STR[] = "Eina List"; -static const char EINA_MAGIC_LIST_ITERATOR_STR[] = "Eina List Iterator"; -static const char EINA_MAGIC_LIST_ACCESSOR_STR[] = "Eina List Accessor"; -static const char EINA_MAGIC_LIST_ACCOUNTING_STR[] = - "Eina List Accounting"; - - -#define EINA_MAGIC_CHECK_LIST(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST); \ - return __VA_ARGS__; \ - } \ - } while(0) - -#define EINA_MAGIC_CHECK_LIST_ITERATOR(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST_ITERATOR)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST_ITERATOR); \ - return __VA_ARGS__; \ - } \ - } while(0) - -#define EINA_MAGIC_CHECK_LIST_ACCESSOR(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST_ACCESSOR)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST_ACCESSOR); \ - return __VA_ARGS__; \ - } \ - } while(0) - -#define EINA_MAGIC_CHECK_LIST_ACCOUNTING(d) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST_ACCOUNTING)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST_ACCOUNTING); \ - return; \ - } \ - } while(0) - -#define EINA_LIST_SORT_STACK_SIZE 32 - -typedef struct _Eina_Iterator_List Eina_Iterator_List; -typedef struct _Eina_Accessor_List Eina_Accessor_List; - -struct _Eina_Iterator_List { - Eina_Iterator iterator; - - const Eina_List *head; - const Eina_List *current; - - EINA_MAGIC}; - -struct _Eina_Accessor_List { - Eina_Accessor accessor; - - const Eina_List *head; - const Eina_List *current; - - unsigned int index; - - EINA_MAGIC}; - -static Eina_Mempool *_eina_list_mp = NULL; -static Eina_Mempool *_eina_list_accounting_mp = NULL; -static int _eina_list_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_list_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_list_log_dom, __VA_ARGS__) - -static inline Eina_List_Accounting - *_eina_list_mempool_accounting_new(__UNUSED__ Eina_List * list) -{ - Eina_List_Accounting *tmp; - - tmp = - eina_mempool_malloc(_eina_list_accounting_mp, - sizeof(Eina_List_Accounting)); - if (!tmp) - return NULL; - - EINA_MAGIC_SET(tmp, EINA_MAGIC_LIST_ACCOUNTING); - - return tmp; -} - -static inline void -_eina_list_mempool_accounting_free(Eina_List_Accounting * accounting) -{ - EINA_MAGIC_CHECK_LIST_ACCOUNTING(accounting); - - EINA_MAGIC_SET(accounting, EINA_MAGIC_NONE); - eina_mempool_free(_eina_list_accounting_mp, accounting); -} - -static inline Eina_List *_eina_list_mempool_list_new(__UNUSED__ Eina_List * - list) -{ - Eina_List *tmp; - - tmp = eina_mempool_malloc(_eina_list_mp, sizeof(Eina_List)); - if (!tmp) - return NULL; - - EINA_MAGIC_SET(tmp, EINA_MAGIC_LIST); - - return tmp; -} - -static inline void _eina_list_mempool_list_free(Eina_List * list) -{ - EINA_MAGIC_CHECK_LIST(list); - - list->accounting->count--; - if (list->accounting->count == 0) - _eina_list_mempool_accounting_free(list->accounting); - - EINA_MAGIC_SET(list, EINA_MAGIC_NONE); - eina_mempool_free(_eina_list_mp, list); -} - -static Eina_List *_eina_list_setup_accounting(Eina_List * list) -{ - EINA_MAGIC_CHECK_LIST(list, NULL); - - list->accounting = _eina_list_mempool_accounting_new(list); - if (!list->accounting) - goto on_error; - - list->accounting->last = list; - list->accounting->count = 1; - - return list; - - on_error: - _eina_list_mempool_list_free(list); - return NULL; -} - -static inline void -_eina_list_update_accounting(Eina_List * list, Eina_List * new_list) -{ - EINA_MAGIC_CHECK_LIST(list); - EINA_MAGIC_CHECK_LIST(new_list); - - list->accounting->count++; - new_list->accounting = list->accounting; -} - -#if 0 -static Eina_Mempool2 _eina_list_mempool = { - sizeof(Eina_List), - 320, - 0, NULL, NULL -}; - -static Eina_Mempool2 _eina_list_accounting_mempool = { - sizeof(Eina_List_Accounting), - 80, - 0, NULL, NULL -}; -#endif - -static Eina_Bool -eina_list_iterator_next(Eina_Iterator_List * it, void **data) -{ - EINA_MAGIC_CHECK_LIST_ITERATOR(it, EINA_FALSE); - - if (!it->current) - return EINA_FALSE; - - *data = eina_list_data_get(it->current); - - it->current = eina_list_next(it->current); - - return EINA_TRUE; -} - -static Eina_Bool -eina_list_iterator_prev(Eina_Iterator_List * it, void **data) -{ - EINA_MAGIC_CHECK_LIST_ITERATOR(it, EINA_FALSE); - - if (!it->current) - return EINA_FALSE; - - *data = eina_list_data_get(it->current); - - it->current = eina_list_prev(it->current); - - return EINA_TRUE; -} - -static Eina_List *eina_list_iterator_get_container(Eina_Iterator_List * it) -{ - EINA_MAGIC_CHECK_LIST_ITERATOR(it, NULL); - - return (Eina_List *) it->head; -} - -static void eina_list_iterator_free(Eina_Iterator_List * it) -{ - EINA_MAGIC_CHECK_LIST_ITERATOR(it); - - MAGIC_FREE(it); -} - -static Eina_Bool -eina_list_accessor_get_at(Eina_Accessor_List * it, unsigned int idx, - void **data) -{ - const Eina_List *over; - unsigned int middle; - unsigned int i; - - EINA_MAGIC_CHECK_LIST_ACCESSOR(it, EINA_FALSE); - - if (idx >= eina_list_count(it->head)) - return EINA_FALSE; - - if (it->index == idx) - over = it->current; - else if (idx > it->index) { - /* After current position. */ - middle = - ((eina_list_count(it->head) - it->index) >> 1) + - it->index; - - if (idx > middle) - /* Go backward from the end. */ - for (i = eina_list_count(it->head) - 1, - over = eina_list_last(it->head); - i > idx && over; - --i, over = eina_list_prev(over)); - else - /* Go forward from current. */ - for (i = it->index, over = it->current; - i < idx && over; - ++i, over = eina_list_next(over)); - } else { - /* Before current position. */ - middle = it->index >> 1; - - if (idx > middle) - /* Go backward from current. */ - for (i = it->index, over = it->current; - i > idx && over; - --i, over = eina_list_prev(over)); - else - /* Go forward from start. */ - for (i = 0, over = it->head; - i < idx && over; - ++i, over = eina_list_next(over)); - } - - if (!over) - return EINA_FALSE; - - it->current = over; - it->index = idx; - - *data = eina_list_data_get(it->current); - return EINA_TRUE; -} - -static Eina_List *eina_list_accessor_get_container(Eina_Accessor_List * it) -{ - EINA_MAGIC_CHECK_LIST_ACCESSOR(it, NULL); - - return (Eina_List *) it->head; -} - -static void eina_list_accessor_free(Eina_Accessor_List * it) -{ - EINA_MAGIC_CHECK_LIST_ACCESSOR(it); - - MAGIC_FREE(it); -} - -static Eina_List *eina_list_sort_rebuild_prev(Eina_List * list) -{ - Eina_List *prev = NULL; - - EINA_MAGIC_CHECK_LIST(list, NULL); - - for (; list; list = list->next) { - list->prev = prev; - prev = list; - } - - return prev; -} - -static Eina_List *eina_list_sort_merge(Eina_List * a, Eina_List * b, - Eina_Compare_Cb func) -{ - Eina_List *first, *last; - - if (func(a->data, b->data) < 0) - a = (last = first = a)->next; - else - b = (last = first = b)->next; - - while (a && b) - if (func(a->data, b->data) < 0) - a = (last = last->next = a)->next; - else - b = (last = last->next = b)->next; - - last->next = a ? a : b; - - return first; -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the list module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the list module of Eina. It is called by - * eina_init(). - * - * This function creates mempool to speed up list node and accounting - * management, using EINA_MEMPOOL environment variable if it is set to - * choose the memory pool type to use. - * - * @see eina_init() - */ -Eina_Bool eina_list_init(void) -{ - const char *choice, *tmp; - - _eina_list_log_dom = eina_log_domain_register("eina_list", - EINA_LOG_COLOR_DEFAULT); - if (_eina_list_log_dom < 0) { - EINA_LOG_ERR("Could not register log domain: eina_list"); - return EINA_FALSE; - } -#ifdef EINA_DEFAULT_MEMPOOL - choice = "pass_through"; -#else - choice = "chained_mempool"; -#endif - tmp = getenv("EINA_MEMPOOL"); - if (tmp && tmp[0]) - choice = tmp; - - _eina_list_mp = eina_mempool_add - (choice, "list", NULL, sizeof(Eina_List), 320); - if (!_eina_list_mp) { - ERR("ERROR: Mempool for list cannot be allocated in list init."); - goto on_init_fail; - } - - _eina_list_accounting_mp = eina_mempool_add - (choice, "list_accounting", NULL, sizeof(Eina_List_Accounting), - 80); - if (!_eina_list_accounting_mp) { - ERR("ERROR: Mempool for list accounting cannot be allocated in list init."); - eina_mempool_del(_eina_list_mp); - goto on_init_fail; - } -#define EMS(n) eina_magic_string_static_set(n, n ## _STR) - EMS(EINA_MAGIC_LIST); - EMS(EINA_MAGIC_LIST_ITERATOR); - EMS(EINA_MAGIC_LIST_ACCESSOR); - EMS(EINA_MAGIC_LIST_ACCOUNTING); -#undef EMS - - return EINA_TRUE; - - on_init_fail: - eina_log_domain_unregister(_eina_list_log_dom); - _eina_list_log_dom = -1; - return EINA_FALSE; -} - -/** - * @internal - * @brief Shut down the list module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the list module set up by - * eina_list_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_list_shutdown(void) -{ - eina_mempool_del(_eina_list_accounting_mp); - eina_mempool_del(_eina_list_mp); - - eina_log_domain_unregister(_eina_list_log_dom); - _eina_list_log_dom = -1; - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_List_Group List - * - * @brief These functions provide double linked list management. - * - * For more information, you can look at the @ref tutorial_list_page. - * - * @{ - */ - -/** - * @brief Append the given data to the given linked list. - * - * @param list The given list. - * @param data The data to append. - * @return A list pointer. - * - * This function appends @p data to @p list. If @p list is @c NULL, a - * new list is returned. On success, a new list pointer that should be - * used in place of the one given to this function is - * returned. Otherwise, the old pointer is returned. - * - * The following example code demonstrates how to ensure that the - * given data has been successfully appended. - * - * @code - * Eina_List *list = NULL; - * extern void *my_data; - * - * list = eina_list_append(list, my_data); - * if (eina_error_get()) - * { - * fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n"); - * exit(-1); - * } - * @endcode - */ -EAPI Eina_List *eina_list_append(Eina_List * list, const void *data) -{ - Eina_List *l, *new_l; - - eina_error_set(0); - new_l = _eina_list_mempool_list_new(list); - if (!new_l) - return list; - - new_l->next = NULL; - new_l->data = (void *) data; - if (!list) { - new_l->prev = NULL; - return _eina_list_setup_accounting(new_l); - } - - EINA_MAGIC_CHECK_LIST(list, NULL); - - l = list->accounting->last; - list->accounting->last = new_l; - - l->next = new_l; - new_l->prev = l; - - _eina_list_update_accounting(list, new_l); - return list; -} - -/** - * @brief Prepends the given data to the given linked list. - * - * @param list The given list. - * @param data The data to prepend. - * @return A list pointer. - * - * This function prepends @p data to @p list. If @p list is @c NULL, a - * new list is returned. On success, a new list pointer that should be - * used in place of the one given to this function is - * returned. Otherwise, the old pointer is returned. - * - * The following example code demonstrates how to ensure that the - * given data has been successfully prepended. - * - * Example: - * @code - * Eina_List *list = NULL; - * extern void *my_data; - * - * list = eina_list_prepend(list, my_data); - * if (eina_error_get()) - * { - * fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n"); - * exit(-1); - * } - * @endcode - */ -EAPI Eina_List *eina_list_prepend(Eina_List * list, const void *data) -{ - Eina_List *new_l; - - eina_error_set(0); - new_l = _eina_list_mempool_list_new(list); - if (!new_l) - return list; - - new_l->prev = NULL; - new_l->next = list; - new_l->data = (void *) data; - - if (!list) - return _eina_list_setup_accounting(new_l); - - EINA_MAGIC_CHECK_LIST(list, NULL); - - list->prev = new_l; - - _eina_list_update_accounting(list, new_l); - - return new_l; -} - -/** - * @brief Insert the given data into the given linked list after the specified data. - * - * @param list The given linked list. - * @param data The data to insert. - * @param relative The data to insert after. - * @return A list pointer. - * - * This function inserts @p data to @p list after @p relative. If - * @p relative is not in the list, @p data is appended to the end of - * the list. If @p list is @c NULL, a new list is returned. If there - * are multiple instances of @p relative in the list, @p data is - * inserted after the first instance.On success, a new list pointer - * that should be used in place of the one given to this function is - * returned. Otherwise, the old pointer is returned. - * - * The following example code demonstrates how to ensure that the - * given data has been successfully inserted. - * - * @code - * Eina_List *list = NULL; - * extern void *my_data; - * extern void *relative_member; - * - * list = eina_list_append(list, relative_member); - * if (eina_error_get()) - * { - * fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n"); - * exit(-1); - * } - * list = eina_list_append_relative(list, my_data, relative_member); - * if (eina_error_get()) - * { - * fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n"); - * exit(-1); - * } - * @endcode - */ -EAPI Eina_List *eina_list_append_relative(Eina_List * list, - const void *data, - const void *relative) -{ - Eina_List *l; - void *list_data; - - if (list) - EINA_MAGIC_CHECK_LIST(list, NULL); - - EINA_LIST_FOREACH(list, l, list_data) { - if (list_data == relative) - return eina_list_append_relative_list(list, data, - l); - } - - return eina_list_append(list, data); -} - -/** - * @brief Append a list node to a linked list after the specified member - * - * @param list The given linked list. - * @param data The data to insert. - * @param relative The list node to insert after. - * @return A list pointer. - * - * This function inserts @p data to @p list after the list node - * @p relative. If @p list or @p relative are @c NULL, @p data is just - * appended to @p list using eina_list_append(). If @p list is - * @c NULL, a new list is returned. If there are multiple instances - * of @p relative in the list, @p data is inserted after the first - * instance. On success, a new list pointer that should be used in - * place of the one given to this function is returned. Otherwise, the - * old pointer is returned. - */ -EAPI Eina_List *eina_list_append_relative_list(Eina_List * list, - const void *data, - Eina_List * relative) -{ - Eina_List *new_l; - - if ((!list) || (!relative)) - return eina_list_append(list, data); - - eina_error_set(0); - new_l = _eina_list_mempool_list_new(list); - if (!new_l) - return list; - - EINA_MAGIC_CHECK_LIST(relative, NULL); - new_l->next = relative->next; - new_l->data = (void *) data; - - if (relative->next) - relative->next->prev = new_l; - - relative->next = new_l; - new_l->prev = relative; - - _eina_list_update_accounting(list, new_l); - - if (!new_l->next) - new_l->accounting->last = new_l; - - return list; -} - -/** - * @brief Prepend a data pointer to a linked list before the specified member - * - * @param list The given linked list. - * @param data The data to insert. - * @param relative The data to insert before. - * @return A list pointer. - * - * This function inserts @p data to @p list before @p relative. If - * @p relative is not in the list, @p data is prepended to the list - * with eina_list_prepend(). If @p list is @c NULL, a new list is - * returned. If there are multiple instances of @p relative in the - * list, @p data is inserted before the first instance. On success, a - * new list pointer that should be used in place of the one given to - * this function is returned. Otherwise, the old pointer is returned. - * - * The following code example demonstrates how to ensure that the - * given data has been successfully inserted. - * - * @code - * Eina_List *list = NULL; - * extern void *my_data; - * extern void *relative_member; - * - * list = eina_list_append(list, relative_member); - * if (eina_error_get_error()) - * { - * fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n"); - * exit(-1); - * } - * list = eina_list_prepend_relative(list, my_data, relative_member); - * if (eina_error_get()) - * { - * fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n"); - * exit(-1); - * } - * @endcode - */ -EAPI Eina_List *eina_list_prepend_relative(Eina_List * list, - const void *data, - const void *relative) -{ - Eina_List *l; - void *list_data; - - if (list) - EINA_MAGIC_CHECK_LIST(list, NULL); - - EINA_LIST_FOREACH(list, l, list_data) { - if (list_data == relative) - return eina_list_prepend_relative_list(list, data, - l); - } - return eina_list_prepend(list, data); -} - -/** - * @brief Prepend a list node to a linked list before the specified member - * - * @param list The given linked list. - * @param data The data to insert. - * @param relative The list node to insert before. - * @return A list pointer. - * - * This function inserts @p data to @p list before the list node - * @p relative. If @p list or @p relative are @c NULL, @p data is just - * prepended to @p list using eina_list_prepend(). If @p list is - * @c NULL, a new list is returned. If there are multiple instances - * of @p relative in the list, @p data is inserted before the first - * instance. On success, a new list pointer that should be used in - * place of the one given to this function is returned. Otherwise, the - * old pointer is returned. - */ -EAPI Eina_List *eina_list_prepend_relative_list(Eina_List * list, - const void *data, - Eina_List * relative) -{ - Eina_List *new_l; - - if ((!list) || (!relative)) - return eina_list_prepend(list, data); - - eina_error_set(0); - new_l = _eina_list_mempool_list_new(list); - if (!new_l) - return list; - - EINA_MAGIC_CHECK_LIST(relative, NULL); - - new_l->prev = relative->prev; - new_l->next = relative; - new_l->data = (void *) data; - - if (relative->prev) - relative->prev->next = new_l; - - relative->prev = new_l; - - _eina_list_update_accounting(list, new_l); - - if (new_l->prev) - return list; - - return new_l; -} - -/** - * @brief Insert a new node into a sorted list. - * - * @param list The given linked list, @b must be sorted. - * @param func The function called for the sort. - * @param data The data to insert sorted. - * @return A list pointer. - * - * This function inserts values into a linked list assuming it was - * sorted and the result will be sorted. If @p list is @c NULLL, a new - * list is returned. On success, a new list pointer that should be - * used in place of the one given to this function is - * returned. Otherwise, the old pointer is returned. See eina_error_get(). - * - * @note O(log2(n)) comparisons (calls to @p func) average/worst case - * performance as it uses eina_list_search_sorted_near_list() and thus - * is bounded to that. As said in eina_list_search_sorted_near_list(), - * lists do not have O(1) access time, so walking to the correct node - * can be costly, consider worst case to be almost O(n) pointer - * dereference (list walk). - */ -EAPI Eina_List *eina_list_sorted_insert(Eina_List * list, - Eina_Compare_Cb func, - const void *data) -{ - Eina_List *lnear; - int cmp; - - if (!list) - return eina_list_append(NULL, data); - - lnear = eina_list_search_sorted_near_list(list, func, data, &cmp); - if (cmp < 0) - return eina_list_append_relative_list(list, data, lnear); - else - return eina_list_prepend_relative_list(list, data, lnear); -} - -/** - * @brief Remove the first instance of the specified data from the given list. - * - * @param list The given list. - * @param data The specified data. - * @return A list pointer. - * - * This function removes the first instance of @p data from - * @p list. If the specified data is not in the given list (tihis - * include the case where @p data is @c NULL), nothing is done. If - * @p list is @c NULL, @c NULL is returned, otherwise a new list - * pointer that should be used in place of the one passed to this - * function. - */ -EAPI Eina_List *eina_list_remove(Eina_List * list, const void *data) -{ - Eina_List *l; - - if (list) - EINA_MAGIC_CHECK_LIST(list, NULL); - - l = eina_list_data_find_list(list, data); - return eina_list_remove_list(list, l); -} - -/** - * @brief Remove the specified data. - * - * @param list The given linked list. - * @param remove_list The list node which is to be removed. - * @return A list pointer. - * - * This function removes the list node @p remove_list from @p list and - * frees the list node structure @p remove_list. If @p list is - * @c NULL, this function returns @c NULL. If @p remove_list is - * @c NULL, it returns @p list, otherwise, a new list pointer that - * should be used in place of the one passed to this function. - * - * The following code gives an example (notice we use EINA_LIST_FOREACH - * instead of EINA_LIST_FOREACH_SAFE because we stop the loop after - * removing the current node). - * - * @code - * extern Eina_List *list; - * Eina_List *l; - * extern void *my_data; - * void *data - * - * EINA_LIST_FOREACH(list, l, data) - * { - * if (data == my_data) - * { - * list = eina_list_remove_list(list, l); - * break; - * } - * } - * @endcode - */ -EAPI Eina_List *eina_list_remove_list(Eina_List * list, - Eina_List * remove_list) -{ - Eina_List *return_l; - - if (!list) - return NULL; - - if (!remove_list) - return list; - - EINA_MAGIC_CHECK_LIST(remove_list, NULL); - - if (remove_list->next) - remove_list->next->prev = remove_list->prev; - - if (remove_list->prev) { - remove_list->prev->next = remove_list->next; - return_l = list; - } else - return_l = remove_list->next; - - if (remove_list == remove_list->accounting->last) { - EINA_MAGIC_CHECK_LIST(list, NULL); - list->accounting->last = remove_list->prev; - } - - _eina_list_mempool_list_free(remove_list); - return return_l; -} - -/** - * @brief Free an entire list and all the nodes, ignoring the data contained. - - * @param list The list to free - * @return A NULL pointer - * - * This function frees all the nodes of @p list. It does not free the - * data of the nodes. To free them, use #EINA_LIST_FREE. - */ -EAPI Eina_List *eina_list_free(Eina_List * list) -{ - Eina_List *l, *free_l; - - if (!list) - return NULL; - - EINA_MAGIC_CHECK_LIST(list, NULL); - - for (l = list; l;) { - free_l = l; - l = l->next; - - _eina_list_mempool_list_free(free_l); - } - - return NULL; -} - -/** - * @brief Move the specified data to the head of the list. - * - * @param list The list handle to move the data. - * @param move_list The list node to move. - * @return A new list handle to replace the old one - * - * This function move @p move_list to the front of @p list. If list is - * @c NULL, @c NULL is returned. If @p move_list is @c NULL, - * @p list is returned. Otherwise, a new list pointer that should be - * used in place of the one passed to this function. - * - * Example: - * @code - * extern Eina_List *list; - * Eina_List *l; - * extern void *my_data; - * void *data; - * - * EINA_LIST_FOREACH(list, l, data) - * { - * if (data == my_data) - * { - * list = eina_list_promote_list(list, l); - * break; - * } - * } - * @endcode - */ -EAPI Eina_List *eina_list_promote_list(Eina_List * list, - Eina_List * move_list) -{ - if (!list) - return NULL; - - if (!move_list) { - return list; /* Promoting head to be head. */ - - } - - if (move_list == list) - return list; - - if (move_list->next == list) - return move_list; - - EINA_MAGIC_CHECK_LIST(list, NULL); - EINA_MAGIC_CHECK_LIST(move_list, NULL); - - /* Remove the promoted item from the list. */ - if (!move_list->prev) - move_list->next->prev = NULL; - else { - move_list->prev->next = move_list->next; - if (move_list == list->accounting->last) - list->accounting->last = move_list->prev; - else - move_list->next->prev = move_list->prev; - } - - /* Add the promoted item in the list. */ - move_list->next = list; - move_list->prev = list->prev; - list->prev = move_list; - if (move_list->prev) - move_list->prev->next = move_list; - - return move_list; -} - -/** - * @brief Move the specified data to the tail of the list. - * - * @param list The list handle to move the data. - * @param move_list The list node to move. - * @return A new list handle to replace the old one - * - * This function move @p move_list to the back of @p list. If list is - * @c NULL, @c NULL is returned. If @p move_list is @c NULL, - * @p list is returned. Otherwise, a new list pointer that should be - * used in place of the one passed to this function. - * - * Example: - * @code - * extern Eina_List *list; - * Eina_List *l; - * extern void *my_data; - * void *data; - * - * EINA_LIST_FOREACH(list, l, data) - * { - * if (data == my_data) - * { - * list = eina_list_demote_list(list, l); - * break; - * } - * } - * @endcode - */ -EAPI Eina_List *eina_list_demote_list(Eina_List * list, - Eina_List * move_list) -{ - if (!list) - return NULL; - - if (!move_list) { - return list; /* Demoting tail to be tail. */ - - } - - if (move_list == list->accounting->last) - return list; - - EINA_MAGIC_CHECK_LIST(list, NULL); - EINA_MAGIC_CHECK_LIST(move_list, NULL); - - /* Update pointer list if necessary. */ - if (list == move_list) { - list = move_list->next; /* Remove the demoted item from the list. */ - - } - - if (move_list->prev) - move_list->prev->next = move_list->next; - - move_list->next->prev = move_list->prev; - /* Add the demoted item in the list. */ - move_list->prev = list->accounting->last; - move_list->prev->next = move_list; - move_list->next = NULL; - list->accounting->last = move_list; - - return list; -} - -/** - * @brief Find a member of a list and return the member. - * - * @param list The list to search for a data. - * @param data The data pointer to find in the list. - * @return The found member data pointer if foun, @c NULL otherwise. - * - * This function searches in @p list from beginning to end for the - * first member whose data pointer is @p data. If it is found, @p data - * will be returned, otherwise NULL will be returned. - * - * Example: - * @code - * extern Eina_List *list; - * extern void *my_data; - * - * if (eina_list_data_find(list, my_data) == my_data) - * { - * printf("Found member %p\n", my_data); - * } - * @endcode - */ -EAPI void *eina_list_data_find(const Eina_List * list, const void *data) -{ - if (eina_list_data_find_list(list, data)) - return (void *) data; - - return NULL; -} - -/** - * @brief Find a member of a list and return the list node containing that member. - * - * @param list The list to search for data. - * @param data The data pointer to find in the list. - * @return The found members list node on success, @c NULL otherwise. - * - * This function searches in @p list from beginning to end for the - * first member whose data pointer is @p data. If it is found, the - * list node containing the specified member is returned, otherwise - * @c NULL is returned. - */ -EAPI Eina_List *eina_list_data_find_list(const Eina_List * list, - const void *data) -{ - const Eina_List *l; - void *list_data; - - if (list) - EINA_MAGIC_CHECK_LIST(list, NULL); - - EINA_LIST_FOREACH(list, l, list_data) { - if (list_data == data) - return (Eina_List *) l; - } - - return NULL; -} - -/** - * @brief Get the nth member's data pointer in a list. - * - * @param list The list to get the specified member number from. - * @param n The number of the element (0 being the first). - * @return The data pointer stored in the specified element. - * - * This function returns the data pointer of element number @p n, in - * the @p list. The first element in the array is element number 0. If - * the element number @p n does not exist, @c NULL is - * returned. Otherwise, the data of the found element is returned. - */ -EAPI void *eina_list_nth(const Eina_List * list, unsigned int n) -{ - Eina_List *l; - - l = eina_list_nth_list(list, n); - return l ? l->data : NULL; -} - -/** - * @brief Get the nth member's list node in a list. - * - * @param list The list to get the specfied member number from. - * @param n The number of the element (0 being the first). - * @return The list node stored in the numbered element. - * - * This function returns the list node of element number @p n, in - * @ list. The first element in the array is element number 0. If the - * element number @p n does not exist or @p list is @c NULL or @p n is - * greater than the count of elements in @p list minus 1, @c NULL is - * returned. Otherwise the list node stored in the numbered element is - * returned. - */ -EAPI Eina_List *eina_list_nth_list(const Eina_List * list, unsigned int n) -{ - const Eina_List *l; - unsigned int i; - - if (list) - EINA_MAGIC_CHECK_LIST(list, NULL); - - /* check for non-existing nodes */ - if ((!list) || (n > (list->accounting->count - 1))) - return NULL; - - /* if the node is in the 2nd half of the list, search from the end - * else, search from the beginning. - */ - if (n > (list->accounting->count / 2)) - for (i = list->accounting->count - 1, - l = list->accounting->last; l; l = l->prev, i--) { - if (i == n) - return (Eina_List *) l; - } else - for (i = 0, l = list; l; l = l->next, i++) { - if (i == n) - return (Eina_List *) l; - } - - abort(); -} - -/** - * @brief Reverse all the elements in the list. - * - * @param list The list to reverse. - * @return The list head after it has been reversed. - * - * This function reverses the order of all elements in @p list, so the - * last member is now first, and so on. If @p list is @c NULL, this - * functon returns @c NULL. - * - * @note @b in-place: this will change the given list, so you should - * now point to the new list head that is returned by this function. - * - * @see eina_list_reverse_clone() - * @see eina_list_iterator_reversed_new() - */ -EAPI Eina_List *eina_list_reverse(Eina_List * list) -{ - Eina_List *l1, *l2; - - if (!list) - return NULL; - - EINA_MAGIC_CHECK_LIST(list, NULL); - - l1 = list; - l2 = list->accounting->last; - while (l1 != l2) { - void *data; - - data = l1->data; - l1->data = l2->data; - l2->data = data; - l1 = l1->next; - if (l1 == l2) - break; - - l2 = l2->prev; - } - - return list; -} - -/** - * @brief Clone (copy) all the elements in the list in reverse order. - * - * @param list The list to reverse. - * @return The new list that has been reversed. - * - * This function reverses the order of all elements in @p list, so the - * last member is now first, and so on. If @p list is @c NULL, this - * functon returns @c NULL. This returns a copy of the given list. - * - * @note @b copy: this will copy the list and you should then - * eina_list_free() when it is not required anymore. - * - * @see eina_list_reverse() - * @see eina_list_clone() - */ -EAPI Eina_List *eina_list_reverse_clone(const Eina_List * list) -{ - const Eina_List *l; - Eina_List *lclone; - void *data; - - if (!list) - return NULL; - - EINA_MAGIC_CHECK_LIST(list, NULL); - - lclone = NULL; - EINA_LIST_FOREACH(list, l, data) - lclone = eina_list_prepend(lclone, data); - - return lclone; -} - -/** - * @brief Clone (copy) all the elements in the list in exact order. - * - * @param list The list to clone. - * @return The new list that has been cloned. - * - * This function clone in order of all elements in @p list. If @p list - * is @c NULL, this functon returns @c NULL. This returns a copy of - * the given list. - * - * @note @b copy: this will copy the list and you should then - * eina_list_free() when it is not required anymore. - * - * @see eina_list_reverse_clone() - */ -EAPI Eina_List *eina_list_clone(const Eina_List * list) -{ - const Eina_List *l; - Eina_List *lclone; - void *data; - - if (!list) - return NULL; - - EINA_MAGIC_CHECK_LIST(list, NULL); - - lclone = NULL; - EINA_LIST_FOREACH(list, l, data) - lclone = eina_list_append(lclone, data); - - return lclone; -} - -/** - * @brief Sort a list according to the ordering func will return. - * - * @param list The list handle to sort. - * @param size The length of the list to sort. - * @param func A function pointer that can handle comparing the list data - * nodes. - * @return the new head of list. - * - * This function sorts @p list. @p size if the number of the first - * element to sort. If @p size is 0 or greater than the number of - * elements in @p list, all the elements are sorted. @p func is used to - * compare two elements of @p list. If @p list or @p func are @c NULL, - * this function returns @c NULL. - * - * @note @b in-place: this will change the given list, so you should - * now point to the new list head that is returned by this function. - * - * @note worst case is O(n * log2(n)) comparisons (calls to func()), - * O(n) comparisons average case. That means that for 1,000,000 list - * elements, sort will usually do 1,000,000 comparisons, but may do up - * to 20,000,000. - * - * Example: - * @code - * int - * sort_cb(const void *d1, const void *d2) - * { - * const char *txt = NULL; - * const char *txt2 = NULL; - * - * if(!d1) return(1); - * if(!d2) return(-1); - * - * return(strcmp((const char*)d1, (const char*)d2)); - * } - * extern Eina_List *list; - * - * list = eina_list_sort(list, eina_list_count(list), sort_cb); - * @endcode - */ -EAPI Eina_List *eina_list_sort(Eina_List * list, unsigned int size, - Eina_Compare_Cb func) -{ - unsigned int i = 0; - unsigned int n = 0; - Eina_List *tail = list; - Eina_List *unsort = NULL; - Eina_List *stack[EINA_LIST_SORT_STACK_SIZE]; - - EINA_SAFETY_ON_NULL_RETURN_VAL(func, list); - if (!list) - return NULL; - - EINA_MAGIC_CHECK_LIST(list, NULL); - - /* if the caller specified an invalid size, sort the whole list */ - if ((size == 0) || (size > list->accounting->count)) - size = list->accounting->count; - - if (size != list->accounting->count) { - unsort = eina_list_nth_list(list, size); - if (unsort) - unsort->prev->next = NULL; - } - - while (tail) { - unsigned int idx, tmp; - - Eina_List *a = tail; - Eina_List *b = tail->next; - - if (!b) { - stack[i++] = a; - break; - } - - tail = b->next; - - if (func(a->data, b->data) < 0) - ((stack[i++] = a)->next = b)->next = 0; - else - ((stack[i++] = b)->next = a)->next = 0; - - tmp = n++; - for (idx = n ^ tmp; idx &= idx - 1; i--) - stack[i - 2] = - eina_list_sort_merge(stack[i - 2], - stack[i - 1], func); - } - - while (i-- > 1) - stack[i - 1] = - eina_list_sort_merge(stack[i - 1], stack[i], func); - - list = stack[0]; - tail = eina_list_sort_rebuild_prev(list); - - if (unsort) { - tail->next = unsort; - unsort->prev = tail; - } else - list->accounting->last = tail; - - return list; -} - -/** - * @brief Merge two list. - * - * @param left Head list to merge. - * @param right Tail list to merge. - * @return A new merged list. - * - * This function put right at the end of left and return the head. - * - * Both left and right does not exist anymore after the merge. - * - * @note merge cost is O(n), being @b n the size of the smallest - * list. This is due the need to fix accounting of that segment, - * making count and last access O(1). - */ -EAPI Eina_List *eina_list_merge(Eina_List * left, Eina_List * right) -{ - unsigned int n_left, n_right; - - if (!left) - return right; - - if (!right) - return left; - - left->accounting->last->next = right; - right->prev = left->accounting->last; - - n_left = left->accounting->count; - n_right = right->accounting->count; - - if (n_left >= n_right) { - Eina_List *itr = right; - left->accounting->last = right->accounting->last; - left->accounting->count += n_right; - - _eina_list_mempool_accounting_free(right->accounting); - - do { - itr->accounting = left->accounting; - itr = itr->next; - } - while (itr); - } else { - Eina_List *itr = left->accounting->last; - right->accounting->count += n_left; - - _eina_list_mempool_accounting_free(left->accounting); - - do { - itr->accounting = right->accounting; - itr = itr->prev; - } - while (itr); - } - - return left; -} - - -/** - * @brief Split a list into 2 lists. - * - * @param list List to split. - * @param relative The list will be split after @p relative. - * @param right The head of the new right list. - * @return The new left list - * - * This function split @p list into two lists ( left and right ) after the node @p relative. @p Relative - * will become the last node of the left list. If @p list or @p right are NULL list is returns. - * If @p relative is NULL right is set to @p list and NULL is returns. - * If @p relative is the last node of @p list list is returns and @p right is set to NULL. - * - * list does not exist anymore after the split. - * - */ -EAPI Eina_List *eina_list_split_list(Eina_List * list, - Eina_List * relative, - Eina_List ** right) -{ - Eina_List *next; - Eina_List *itr; - - if (!right) - return list; - - *right = NULL; - - if (!list) - return NULL; - - if (!relative) { - *right = list; - return NULL; - } - - if (relative == eina_list_last(list)) - return list; - - next = eina_list_next(relative); - next->prev = NULL; - next->accounting = _eina_list_mempool_accounting_new(next); - next->accounting->last = list->accounting->last; - *right = next; - - itr = next; - do { - itr->accounting = next->accounting; - next->accounting->count++; - itr = itr->next; - } - while (itr); - - relative->next = NULL; - list->accounting->last = relative; - list->accounting->count = - list->accounting->count - next->accounting->count; - - return list; -} - -/** - * @brief Merge two sorted list according to the ordering func will return. - * - * @param left First list to merge. - * @param right Second list to merge. - * @param func A function pointer that can handle comparing the list data - * nodes. - * @return A new sorted list. - * - * This function compare the head of @p left and @p right, and choose the - * smallest one to be head of the returned list. It will continue this process - * for all entry of both list. - * - * Both left and right does not exist anymore after the merge. - * If @p func is NULL, it will return NULL. - * - * Example: - * @code - * int - * sort_cb(void *d1, void *d2) - * { - * const char *txt = NULL; - * const char *txt2 = NULL; - * - * if(!d1) return(1); - * if(!d2) return(-1); - * - * return(strcmp((const char*)d1, (const char*)d2)); - * } - * extern Eina_List *sorted1; - * extern Eina_List *sorted2; - * - * list = eina_list_sorted_merge(sorted1, sorted2, sort_cb); - * @endcode - */ -EAPI Eina_List *eina_list_sorted_merge(Eina_List * left, Eina_List * right, - Eina_Compare_Cb func) -{ - Eina_List *ret; - Eina_List *current; - - EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL); - - if (!left) - return right; - - if (!right) - return left; - - if (func(left->data, right->data) < 0) { - ret = left; - current = left; - left = left->next; - ret->accounting->count += right->accounting->count; - - _eina_list_mempool_accounting_free(right->accounting); - } else { - ret = right; - current = right; - right = right->next; - ret->accounting->count += left->accounting->count; - - _eina_list_mempool_accounting_free(left->accounting); - } - - while (left && right) { - if (func(left->data, right->data) < 0) { - current->next = left; - left->prev = current; - left = left->next; - } else { - current->next = right; - right->prev = current; - right = right->next; - } - - current = current->next; - current->accounting = ret->accounting; - } - - if (left) { - current->next = left; - left->prev = current; - current->accounting = ret->accounting; - } - - if (right) { - current->next = right; - right->prev = current; - current->accounting = ret->accounting; - } - - while (current->next) { - current = current->next; - current->accounting = ret->accounting; - } - - ret->accounting->last = current; - - return ret; -} - -/** - * @brief Returns node nearest to data is in the sorted list. - * - * @param list The list to search for data, @b must be sorted. - * @param func A function pointer that can handle comparing the list data nodes. - * @param data reference value to search. - * @param result_cmp if provided returns the result of - * func(node->data, data) node being the last (returned) node. If node - * was found (exact match), then it is 0. If returned node is smaller - * than requested data, it is less than 0 and if it's bigger it's - * greater than 0. It is the last value returned by func(). - * @return the nearest node, NULL if not found. - * - * This can be used to check if some value is inside the list and get - * the nearest container node in this case. It should be used when list is - * known to be sorted as it will do binary search for results. - * - * Example: imagine user gives a string, you check if it's in the list - * before duplicating its contents, otherwise you want to insert it - * sorted. In this case you get the result of this function and either - * append or prepend the value. - * - * @note O(log2(n)) average/worst case performance, for 1,000,000 - * elements it will do a maximum of 20 comparisons. This is much - * faster than the 1,000,000 comparisons made naively walking the list - * from head to tail, so depending on the number of searches and - * insertions, it may be worth to eina_list_sort() the list and do the - * searches later. As lists do not have O(1) access time, walking to - * the correct node can be costly, consider worst case to be almost - * O(n) pointer dereference (list walk). - * - * @see eina_list_search_sorted_list() - * @see eina_list_sort() - * @see eina_list_sorted_merge() - */ -EAPI Eina_List *eina_list_search_sorted_near_list(const Eina_List * list, - Eina_Compare_Cb func, - const void *data, - int *result_cmp) -{ - const Eina_List *ct; - unsigned int inf, sup, cur; - int cmp; - - if (!list) { - if (result_cmp) - *result_cmp = 0; - - return NULL; - } - - if (list->accounting->count == 1) { - if (result_cmp) - *result_cmp = func(list->data, data); - - return (Eina_List *) list; - } - - /* list walk is expensive, do quick check: tail */ - ct = list->accounting->last; - cmp = func(ct->data, data); - if (cmp <= 0) - goto end; - - /* list walk is expensive, do quick check: head */ - ct = list; - cmp = func(ct->data, data); - if (cmp >= 0) - goto end; - - /* inclusive bounds */ - inf = 1; - sup = list->accounting->count - 2; - cur = 1; - ct = list->next; - - /* no loop, just compare if comparison value is important to caller */ - if (inf > sup) { - if (result_cmp) - cmp = func(ct->data, data); - - goto end; - } - - while (inf <= sup) { - unsigned int tmp = cur; - cur = inf + ((sup - inf) >> 1); - if (tmp < cur) - for (; tmp != cur; tmp++, ct = ct->next); - else if (tmp > cur) - for (; tmp != cur; tmp--, ct = ct->prev); - - cmp = func(ct->data, data); - if (cmp == 0) - break; - else if (cmp < 0) - inf = cur + 1; - else if (cmp > 0) { - if (cur > 0) - sup = cur - 1; - else - break; - } else - break; - } - - end: - if (result_cmp) - *result_cmp = cmp; - - return (Eina_List *) ct; -} - -/** - * @brief Returns node if data is in the sorted list. - * - * @param list The list to search for data, @b must be sorted. - * @param func A function pointer that can handle comparing the list data nodes. - * @param data reference value to search. - * @return the node if func(node->data, data) == 0, NULL if not found. - * - * This can be used to check if some value is inside the list and get - * the container node in this case. It should be used when list is - * known to be sorted as it will do binary search for results. - * - * Example: imagine user gives a string, you check if it's in the list - * before duplicating its contents. - * - * @note O(log2(n)) average/worst case performance, for 1,000,000 - * elements it will do a maximum of 20 comparisons. This is much - * faster than the 1,000,000 comparisons made by - * eina_list_search_unsorted_list(), so depending on the number of - * searches and insertions, it may be worth to eina_list_sort() the - * list and do the searches later. As said in - * eina_list_search_sorted_near_list(), lists do not have O(1) access - * time, so walking to the correct node can be costly, consider worst - * case to be almost O(n) pointer dereference (list walk). - * - * @see eina_list_search_sorted() - * @see eina_list_sort() - * @see eina_list_sorted_merge() - * @see eina_list_search_unsorted_list() - * @see eina_list_search_sorted_near_list() - */ -EAPI Eina_List *eina_list_search_sorted_list(const Eina_List * list, - Eina_Compare_Cb func, - const void *data) -{ - Eina_List *lnear; - int cmp; - - lnear = eina_list_search_sorted_near_list(list, func, data, &cmp); - if (!lnear) - return NULL; - - if (cmp == 0) - return lnear; - - return NULL; -} - - -/** - * @brief Returns node data if it is in the sorted list. - * - * @param list The list to search for data, @b must be sorted. - * @param func A function pointer that can handle comparing the list data nodes. - * @param data reference value to search. - * @return the node value (@c node->data) if func(node->data, data) == 0, - * NULL if not found. - * - * This can be used to check if some value is inside the list and get - * the existing instance in this case. It should be used when list is - * known to be sorted as it will do binary search for results. - * - * Example: imagine user gives a string, you check if it's in the list - * before duplicating its contents. - * - * @note O(log2(n)) average/worst case performance, for 1,000,000 - * elements it will do a maximum of 20 comparisons. This is much - * faster than the 1,000,000 comparisons made by - * eina_list_search_unsorted(), so depending on the number of - * searches and insertions, it may be worth to eina_list_sort() the - * list and do the searches later. As said in - * eina_list_search_sorted_near_list(), lists do not have O(1) access - * time, so walking to the correct node can be costly, consider worst - * case to be almost O(n) pointer dereference (list walk). - * - * @see eina_list_search_sorted_list() - * @see eina_list_sort() - * @see eina_list_sorted_merge() - * @see eina_list_search_unsorted_list() - */ -EAPI void *eina_list_search_sorted(const Eina_List * list, - Eina_Compare_Cb func, const void *data) -{ - return - eina_list_data_get(eina_list_search_sorted_list - (list, func, data)); -} - -/** - * @brief Returns node if data is in the unsorted list. - * - * @param list The list to search for data, may be unsorted. - * @param func A function pointer that can handle comparing the list data nodes. - * @param data reference value to search. - * @return the node if func(node->data, data) == 0, NULL if not found. - * - * This can be used to check if some value is inside the list and get - * the container node in this case. - * - * Example: imagine user gives a string, you check if it's in the list - * before duplicating its contents. - * - * @note this is expensive and may walk the whole list, it's order-N, - * that is for 1,000,000 elements list it may walk and compare - * 1,000,000 nodes. - * - * @see eina_list_search_sorted_list() - * @see eina_list_search_unsorted() - */ -EAPI Eina_List *eina_list_search_unsorted_list(const Eina_List * list, - Eina_Compare_Cb func, - const void *data) -{ - const Eina_List *l; - void *d; - - EINA_LIST_FOREACH(list, l, d) { - if (!func(d, data)) - return (Eina_List *) l; - } - return NULL; -} - -/** - * @brief Returns node data if it is in the unsorted list. - * - * @param list The list to search for data, may be unsorted. - * @param func A function pointer that can handle comparing the list data nodes. - * @param data reference value to search. - * @return the node value (@c node->data) if func(node->data, data) == 0, - * NULL if not found. - * - * This can be used to check if some value is inside the list and get - * the existing instance in this case. - * - * Example: imagine user gives a string, you check if it's in the list - * before duplicating its contents. - * - * @note this is expensive and may walk the whole list, it's order-N, - * that is for 1,000,000 elements list it may walk and compare - * 1,000,000 nodes. - * - * @see eina_list_search_sorted() - * @see eina_list_search_unsorted_list() - */ -EAPI void *eina_list_search_unsorted(const Eina_List * list, - Eina_Compare_Cb func, - const void *data) -{ - return - eina_list_data_get(eina_list_search_unsorted_list - (list, func, data)); -} - - -/** - * @brief Returned a new iterator associated to a list. - * - * @param list The list. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * list. If @p list is @c NULL or the count member of @p list is less - * or equal than 0, this function still returns a valid iterator that - * will always return false on eina_iterator_next(), thus keeping API - * sane. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the list structure changes then the iterator becomes - * invalid! That is, if you add or remove nodes this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_list_iterator_new(const Eina_List * list) -{ - Eina_Iterator_List *it; - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_List)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(it, EINA_MAGIC_LIST_ITERATOR); - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->head = list; - it->current = list; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(eina_list_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(eina_list_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(eina_list_iterator_free); - - return &it->iterator; -} - -/** - * @brief Returned a new reversed iterator associated to a list. - * - * @param list The list. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * list. If @p list is @c NULL or the count member of @p list is less - * or equal than 0, this function still returns a valid iterator that - * will always return false on eina_iterator_next(), thus keeping API - * sane. - * - * Unlike eina_list_iterator_new(), this will walk the list backwards. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the list structure changes then the iterator becomes - * invalid! That is, if you add or remove nodes this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_list_iterator_reversed_new(const Eina_List * list) -{ - Eina_Iterator_List *it; - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_List)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(it, EINA_MAGIC_LIST_ITERATOR); - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->head = eina_list_last(list); - it->current = it->head; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(eina_list_iterator_prev); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(eina_list_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(eina_list_iterator_free); - - return &it->iterator; -} - -/** - * @brief Returned a new accessor associated to a list. - * - * @param list The list. - * @return A new accessor. - * - * This function returns a newly allocated accessor associated to - * @p list. If @p list is @c NULL or the count member of @p list is - * less or equal than 0, this function returns NULL. If the memory can - * not be allocated, NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is - * set. Otherwise, a valid accessor is returned. - */ -EAPI Eina_Accessor *eina_list_accessor_new(const Eina_List * list) -{ - Eina_Accessor_List *ac; - - eina_error_set(0); - ac = calloc(1, sizeof(Eina_Accessor_List)); - if (!ac) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(ac, EINA_MAGIC_LIST_ACCESSOR); - EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); - - ac->head = list; - ac->current = list; - ac->index = 0; - - ac->accessor.version = EINA_ACCESSOR_VERSION; - ac->accessor.get_at = - FUNC_ACCESSOR_GET_AT(eina_list_accessor_get_at); - ac->accessor.get_container = - FUNC_ACCESSOR_GET_CONTAINER(eina_list_accessor_get_container); - ac->accessor.free = FUNC_ACCESSOR_FREE(eina_list_accessor_free); - - return &ac->accessor; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_log.c b/tests/suite/ecore/src/lib/eina_log.c deleted file mode 100644 index 18a414bcfa..0000000000 --- a/tests/suite/ecore/src/lib/eina_log.c +++ /dev/null @@ -1,2375 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2009 Jorge Luis Zapata Muga, Cedric Bail, Andre Dieb - * Martins - * - * 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 <https://www.gnu.org/licenses/>. - */ - - -/** - * @page tutorial_log_page Log Tutorial - * - * @section tutorial_log_introduction Introduction - * - * The Eina Log module provides logging facilities for libraries and - * applications. It provides colored logging, basic logging levels (error, - * warning, debug, info, critical) and loggers - called logging domains - - * which will be covered on next sections. - * - * @section tutorial_log_basic_usage Basic Usage - * - * Log messages can be displayed using the following macros: - * - * @li EINA_LOG_ERR(), - * @li EINA_LOG_INFO(), - * @li EINA_LOG_WARN(), - * @li EINA_LOG_DBG(). - * - * Here is an example: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * - * #include <Eina.h> - * - * void test(int i) - * { - * EINA_LOG_DBG("Entering test"); - * - * if (i < 0) - * { - * EINA_LOG_ERR("Argument is negative"); - * return; - * } - * - * EINA_LOG_INFO("argument non negative"); - * - * EINA_LOG_DBG("Exiting test"); - * } - * - * int main(void) - * { - * if (!eina_init()) - * { - * printf("log during the initialization of Eina_Log module\n"); - * return EXIT_FAILURE; - * } - * - * test(-1); - * test(0); - * - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - * If you compiled Eina without debug mode, execution will yield only one log - * message, which is "argument is negative". - * - * Here we introduce the concept of logging domains (or loggers), which might - * already be familiar to readers. It is basically a way to separate a set of - * log messages into a context (e.g. a module) and provide a way of controlling - * this set as a whole. - * - * For example, suppose you have 3 different modules on your application and you - * want to get logging only from one of them (e.g. create some sort of filter). - * For achieving that, all you need to do is create a logging domain for each - * module so that all logging inside a module can be considered as a whole. - * - * Logging domains are specified by a name, color applied to the name and the - * level. The first two (name and color) are set through code, that is, inside - * your application/module/library. - * - * The level is used for controlling which messages should appear. It - * specifies the lowest level that should be displayed (e.g. a message - * with level 11 being logged on a domain with level set to 10 would be - * displayed, while a message with level 9 wouldn't). - * - * The domain level is set during runtime (in contrast with the name and - * color) through the environment variable EINA_LOG_LEVELS. This variable - * expects a list in the form domain_name1:level1,domain_name2:level2,... . For - * example: - * - * @code - * - * EINA_LOG_LEVELS=mymodule1:5,mymodule2:2,mymodule3:0 ./myapp - * - * @endcode - * - * This line would set mymodule1 level to 5, mymodule2 level to 2 and mymodule3 - * level to 0. - * - * - * There's also a global logger to which EINA_LOG_(ERR, DBG, INFO, CRIT, WARN) - * macros do log on. It is a logger that is created internally by Eina Log with - * an empty name and can be used for general logging (where logging domains do - * not apply). - * - * Since this global logger doesn't have a name, you can't set its level through - * EINA_LOG_LEVELS variable. Here we introduce a second environment variable - * that is a bit more special: EINA_LOG_LEVEL. - * - * This variable specifies the level of the global logging domain and the level - * of domains that haven't been set through EINA_LOG_LEVELS. Here's an example: - * - * @code - * - * EINA_LOG_LEVEL=3 EINA_LOG_LEVELS=module1:10,module3:2 ./myapp - * - * @endcode - * - * Supposing you have modules named "module1", "module2" and "module3", this - * line would result in module1 with level 10, module2 with level 3 and module3 - * with level 2. Note that module2's level wasn't specified, so it's level is - * set to the global level. This way we can easily apply filters to multiple - * domains with only one parameter (EINA_LOG_LEVEL=num). - * - * The global level (EINA_LOG_LEVEL) can also be set through code, using - * eina_log_level_set() function. - * - * - * While developing your libraries or applications, you may notice that - * EINA_LOG_DOM_(ERR, DBG, INFO, CRIT, WARN) macros also print out - * messages from eina itself. Here we introduce another environment variable - * that is a bit more special: EINA_LOG_LEVELS_GLOB. - * - * This variable allows you to disable the logging of any/all code in eina itself. - * This is useful when developing your libraries or applications so that you can - * see your own domain's messages easier without having to sift through a lot of - * internal eina debug messages. Here's an example: - * - * @code - * - * EINA_LOG_LEVEL=3 EINA_LOG_LEVELS_GLOB=eina_*:0 ./myapp - * - * @endcode - * - * This will disable eina_log output from all internal eina code thus allowing - * you to see your own domain messages easier. - * - * @section tutorial_log_advanced_display Advanced usage of print callbacks - * - * The log module allows the user to change the way - * eina_log_print() displays the messages. It suffices to pass to - * eina_log_print_cb_set() the function used to display the - * message. That function must be of type #Eina_Log_Print_Cb. As a - * custom data can be passed to that callback, powerful display - * messages can be displayed. - * - * It is suggested to not use __FILE__, __FUNCTION__ or __LINE__ when - * writing that callback, but when defining macros (like - * EINA_LOG_ERR() and other macros). - * - * Here is an example of custom callback, whose behavior can be - * changed at runtime: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * - * #include <eina_log.h> - * - * #define log(fmt, ...) \ - * eina_log_print(EINA_LOG_LEVEL_ERR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) - * - * typedef struct _Data Data; - * - * struct _Data - * { - * int to_stderr; - * }; - * - * void print_cb(const Eina_Log_Domain *domain, - * Eina_Log_Level level, - * const char *file, - * const char *fnc, - * int line, - * const char *fmt, - * void *data, - * va_list args) - * { - * Data *d; - * FILE *output; - * char *str; - * - * d = (Data *)data; - * if (d->to_stderr) - * { - * output = stderr; - * str = "stderr"; - * } - * else - * { - * output = stdout; - * str = "stdout"; - * } - * - * fprintf(output, "%s:%s:%s (%d) %s: ", - * domain->domain_str, file, fnc, line, str); - * vfprintf(output, fmt, args); - * putc('\n', output); - * } - * - * void test(Data *data, int i) - * { - * if (i < 0) - * data->to_stderr = 0; - * else - * data->to_stderr = 1; - * - * log("log message..."); - * } - * - * int main(void) - * { - * Data data; - * - * if (!eina_init()) - * { - * printf("log during the initialization of Eina_Log module\n"); - * return EXIT_FAILURE; - * } - * - * eina_log_print_cb_set(print_cb, &data); - * - * test(&data, -1); - * test(&data, 0); - * - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <fnmatch.h> -#include <assert.h> - -#ifndef _MSC_VER -#include <unistd.h> -#endif - -#ifdef EFL_HAVE_POSIX_THREADS -#include <pthread.h> -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_inlist.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_log.h" - -/* TODO - * + printing logs to stdout or stderr can be implemented - * using a queue, useful for multiple threads printing - * + add a wrapper for assert? - */ - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -#define EINA_LOG_ENV_ABORT "EINA_LOG_ABORT" -#define EINA_LOG_ENV_ABORT_LEVEL "EINA_LOG_ABORT_LEVEL" -#define EINA_LOG_ENV_LEVEL "EINA_LOG_LEVEL" -#define EINA_LOG_ENV_LEVELS "EINA_LOG_LEVELS" -#define EINA_LOG_ENV_LEVELS_GLOB "EINA_LOG_LEVELS_GLOB" -#define EINA_LOG_ENV_COLOR_DISABLE "EINA_LOG_COLOR_DISABLE" -#define EINA_LOG_ENV_FILE_DISABLE "EINA_LOG_FILE_DISABLE" -#define EINA_LOG_ENV_FUNCTION_DISABLE "EINA_LOG_FUNCTION_DISABLE" - - -// Structure for storing domain level settings passed from the command line -// that will be matched with application-defined domains. -typedef struct _Eina_Log_Domain_Level_Pending - Eina_Log_Domain_Level_Pending; -struct _Eina_Log_Domain_Level_Pending { - EINA_INLIST; - unsigned int level; - size_t namelen; - char name[]; -}; - -/* - * List of levels for domains set by the user before the domains are registered, - * updates the domain levels on the first log and clears itself. - */ -static Eina_Inlist *_pending_list = NULL; -static Eina_Inlist *_glob_list = NULL; - -// Disable color flag (can be changed through the env var -// EINA_LOG_ENV_COLOR_DISABLE). -static Eina_Bool _disable_color = EINA_FALSE; -static Eina_Bool _disable_file = EINA_FALSE; -static Eina_Bool _disable_function = EINA_FALSE; -static Eina_Bool _abort_on_critical = EINA_FALSE; -static int _abort_level_on_critical = EINA_LOG_LEVEL_CRITICAL; - -#ifdef EFL_HAVE_THREADS - -static Eina_Bool _threads_enabled = EINA_FALSE; - -#ifdef EFL_HAVE_POSIX_THREADS - -typedef pthread_t Thread; - -static pthread_t _main_thread; - -#define SELF() pthread_self() -#define IS_MAIN(t) pthread_equal(t, _main_thread) -#define IS_OTHER(t) EINA_UNLIKELY(!IS_MAIN(t)) -#define CHECK_MAIN(...) \ - do { \ - if (!IS_MAIN(pthread_self())) { \ - fprintf(stderr, \ - "ERR: not main thread! current=%lu, main=%lu\n", \ - (unsigned long)pthread_self(), \ - (unsigned long)_main_thread); \ - return __VA_ARGS__; \ - } \ - } while (0) - -#ifdef EFL_HAVE_POSIX_THREADS_SPINLOCK - -static pthread_spinlock_t _log_lock; -#define LOG_LOCK() \ - if (_threads_enabled) \ - do { \ - if (0) { \ - fprintf(stderr, "+++LOG LOG_LOCKED! [%s, %lu]\n", \ - __FUNCTION__, (unsigned long)pthread_self()); } \ - if (EINA_UNLIKELY(_threads_enabled)) { \ - pthread_spin_lock(&_log_lock); } \ - } while (0) -#define LOG_UNLOCK() \ - if (_threads_enabled) \ - do { \ - if (EINA_UNLIKELY(_threads_enabled)) { \ - pthread_spin_unlock(&_log_lock); } \ - if (0) { \ - fprintf(stderr, \ - "---LOG LOG_UNLOCKED! [%s, %lu]\n", \ - __FUNCTION__, (unsigned long)pthread_self()); } \ - } while (0) -#define INIT() pthread_spin_init(&_log_lock, PTHREAD_PROCESS_PRIVATE) -#define SHUTDOWN() pthread_spin_destroy(&_log_lock) - -#else /* ! EFL_HAVE_POSIX_THREADS_SPINLOCK */ - -static pthread_mutex_t _log_mutex = PTHREAD_MUTEX_INITIALIZER; -#define LOG_LOCK() if(_threads_enabled) {pthread_mutex_lock(&_log_mutex); } -#define LOG_UNLOCK() if(_threads_enabled) {pthread_mutex_unlock(&_log_mutex); } -#define INIT() (1) -#define SHUTDOWN() do {} while (0) - -#endif /* ! EFL_HAVE_POSIX_THREADS_SPINLOCK */ - -#else /* EFL_HAVE_WIN32_THREADS */ - -typedef DWORD Thread; - -static DWORD _main_thread; - -#define SELF() GetCurrentThreadId() -#define IS_MAIN(t) (t == _main_thread) -#define IS_OTHER(t) EINA_UNLIKELY(!IS_MAIN(t)) -#define CHECK_MAIN(...) \ - do { \ - if (!IS_MAIN(GetCurrentThreadId())) { \ - fprintf(stderr, \ - "ERR: not main thread! current=%lu, main=%lu\n", \ - GetCurrentThreadId(), _main_thread); \ - return __VA_ARGS__; \ - } \ - } while (0) - -static HANDLE _log_mutex = NULL; - -#define LOG_LOCK() if(_threads_enabled) WaitForSingleObject(_log_mutex, INFINITE) -#define LOG_UNLOCK() if(_threads_enabled) ReleaseMutex(_log_mutex) -#define INIT() ((_log_mutex = CreateMutex(NULL, FALSE, NULL)) ? 1 : 0) -#define SHUTDOWN() if (_log_mutex) CloseHandle(_log_mutex) - -#endif /* EFL_HAVE_WIN32_THREADS */ - -#else /* ! EFL_HAVE_THREADS */ - -#define LOG_LOCK() do {} while (0) -#define LOG_UNLOCK() do {} while (0) -#define IS_MAIN(t) (1) -#define IS_OTHER(t) (0) -#define CHECK_MAIN(...) do {} while (0) -#define INIT() (1) -#define SHUTDOWN() do {} while (0) - -#endif /* ! EFL_HAVE_THREADS */ - - -// List of domains registered -static Eina_Log_Domain *_log_domains = NULL; -static unsigned int _log_domains_count = 0; -static size_t _log_domains_allocated = 0; - -// Default function for printing on domains -static Eina_Log_Print_Cb _print_cb = eina_log_print_cb_stderr; -static void *_print_cb_data = NULL; - -#ifdef DEBUG -static Eina_Log_Level _log_level = EINA_LOG_LEVEL_DBG; -#elif DEBUG_CRITICAL -static Eina_Log_Level _log_level = EINA_LOG_LEVEL_CRITICAL; -#else -static Eina_Log_Level _log_level = EINA_LOG_LEVEL_ERR; -#endif - -/* NOTE: if you change this, also change: - * eina_log_print_level_name_get() - * eina_log_print_level_name_color_get() - */ -static const char *_names[] = { - "CRI", - "ERR", - "WRN", - "INF", - "DBG", -}; - -#ifdef _WIN32 -static int eina_log_win32_color_get(const char *domain_str) -{ - char *str; - char *tmp; - char *tmp2; - int code = -1; - int lighted = 0; - int ret = 0; - - str = strdup(domain_str); - if (!str) - return 0; - - /* this should not append */ - if (str[0] != '\033') { - free(str); - return 0; - } - - /* we skip the first char and the [ */ - tmp = tmp2 = str + 2; - while (*tmp != 'm') { - if (*tmp == ';') { - *tmp = '\0'; - code = atol(tmp2); - tmp++; - tmp2 = tmp; - } - - tmp++; - } - *tmp = '\0'; - if (code < 0) - code = atol(tmp2); - else - lighted = atol(tmp2); - - free(str); - - if (code < lighted) { - int c; - - c = code; - code = lighted; - lighted = c; - } - - if (lighted) - ret = FOREGROUND_INTENSITY; - - if (code == 31) - ret |= FOREGROUND_RED; - else if (code == 32) - ret |= FOREGROUND_GREEN; - else if (code == 33) - ret |= FOREGROUND_RED | FOREGROUND_GREEN; - else if (code == 34) - ret |= FOREGROUND_BLUE; - else if (code == 36) - ret |= FOREGROUND_GREEN | FOREGROUND_BLUE; - else if (code == 37) - ret |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - - return ret; -} -#endif - -static inline void -eina_log_print_level_name_get(int level, const char **p_name) -{ - static char buf[4]; - /* NOTE: if you change this, also change - * eina_log_print_level_name_color_get() - * eina_log_level_name_get() (at eina_inline_log.x) - */ - if (EINA_UNLIKELY(level < 0)) { - snprintf(buf, sizeof(buf), "%03d", level); - *p_name = buf; - } else if (EINA_UNLIKELY(level >= EINA_LOG_LEVELS)) { - snprintf(buf, sizeof(buf), "%03d", level); - *p_name = buf; - } else - *p_name = _names[level]; -} - -#ifdef _WIN32 -static inline void -eina_log_print_level_name_color_get(int level, - const char **p_name, int *p_color) -{ - static char buf[4]; - /* NOTE: if you change this, also change: - * eina_log_print_level_name_get() - */ - if (EINA_UNLIKELY(level < 0)) { - snprintf(buf, sizeof(buf), "%03d", level); - *p_name = buf; - } else if (EINA_UNLIKELY(level >= EINA_LOG_LEVELS)) { - snprintf(buf, sizeof(buf), "%03d", level); - *p_name = buf; - } else - *p_name = _names[level]; - - *p_color = - eina_log_win32_color_get(eina_log_level_color_get(level)); -} -#else -static inline void -eina_log_print_level_name_color_get(int level, - const char **p_name, - const char **p_color) -{ - static char buf[4]; - /* NOTE: if you change this, also change: - * eina_log_print_level_name_get() - */ - if (EINA_UNLIKELY(level < 0)) { - snprintf(buf, sizeof(buf), "%03d", level); - *p_name = buf; - } else if (EINA_UNLIKELY(level >= EINA_LOG_LEVELS)) { - snprintf(buf, sizeof(buf), "%03d", level); - *p_name = buf; - } else - *p_name = _names[level]; - - *p_color = eina_log_level_color_get(level); -} -#endif - -#define DECLARE_LEVEL_NAME(level) const char *name; \ - eina_log_print_level_name_get(level, &name) -#ifdef _WIN32 -#define DECLARE_LEVEL_NAME_COLOR(level) const char *name; int color; \ - eina_log_print_level_name_color_get(level, &name, &color) -#else -#define DECLARE_LEVEL_NAME_COLOR(level) const char *name, *color; \ - eina_log_print_level_name_color_get(level, &name, &color) -#endif - -/** No threads, No color */ -static void -eina_log_print_prefix_NOthreads_NOcolor_file_func(FILE * fp, - const Eina_Log_Domain * - d, Eina_Log_Level level, - const char *file, - const char *fnc, - int line) -{ - DECLARE_LEVEL_NAME(level); - fprintf(fp, "%s:%s %s:%d %s() ", name, d->domain_str, file, line, - fnc); -} - -static void -eina_log_print_prefix_NOthreads_NOcolor_NOfile_func(FILE * fp, - const Eina_Log_Domain * - d, - Eina_Log_Level level, - const char *file - __UNUSED__, - const char *fnc, - int line __UNUSED__) -{ - DECLARE_LEVEL_NAME(level); - fprintf(fp, "%s:%s %s() ", name, d->domain_str, fnc); -} - -static void -eina_log_print_prefix_NOthreads_NOcolor_file_NOfunc(FILE * fp, - const Eina_Log_Domain * - d, - Eina_Log_Level level, - const char *file, - const char *fnc - __UNUSED__, int line) -{ - DECLARE_LEVEL_NAME(level); - fprintf(fp, "%s:%s %s:%d ", name, d->domain_str, file, line); -} - -/* No threads, color */ -static void -eina_log_print_prefix_NOthreads_color_file_func(FILE * fp, - const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, int line) -{ - DECLARE_LEVEL_NAME_COLOR(level); -#ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color); - fprintf(fp, "%s", name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, ":"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - eina_log_win32_color_get(d->domain_str)); - fprintf(fp, "%s", d->name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, " %s:%d ", file, line); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_INTENSITY | FOREGROUND_RED | - FOREGROUND_GREEN | FOREGROUND_BLUE); - fprintf(fp, "%s()", fnc); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, " "); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s %s:%d " - EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", - color, name, d->domain_str, file, line, fnc); -#endif -} - -static void -eina_log_print_prefix_NOthreads_color_NOfile_func(FILE * fp, - const Eina_Log_Domain * - d, Eina_Log_Level level, - const char *file - __UNUSED__, - const char *fnc, - int line __UNUSED__) -{ - DECLARE_LEVEL_NAME_COLOR(level); -#ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color); - fprintf(fp, "%s", name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, ":"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - eina_log_win32_color_get(d->domain_str)); - fprintf(fp, "%s", d->name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_INTENSITY | FOREGROUND_RED | - FOREGROUND_GREEN | FOREGROUND_BLUE); - fprintf(fp, "%s()", fnc); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, " "); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s " - EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", - color, name, d->domain_str, fnc); -#endif -} - -static void -eina_log_print_prefix_NOthreads_color_file_NOfunc(FILE * fp, - const Eina_Log_Domain * - d, Eina_Log_Level level, - const char *file, - const char *fnc - __UNUSED__, int line) -{ - DECLARE_LEVEL_NAME_COLOR(level); -#ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color); - fprintf(fp, "%s", name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, ":"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - eina_log_win32_color_get(d->domain_str)); - fprintf(fp, "%s", d->name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, " %s:%d ", file, line); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s %s:%d ", - color, name, d->domain_str, file, line); -#endif -} - -/** threads, No color */ -#ifdef EFL_HAVE_THREADS -static void -eina_log_print_prefix_threads_NOcolor_file_func(FILE * fp, - const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, int line) -{ - Thread cur; - - DECLARE_LEVEL_NAME(level); - cur = SELF(); - if (IS_OTHER(cur)) { - fprintf(fp, "%s:%s[T:%lu] %s:%d %s() ", - name, d->domain_str, (unsigned long) cur, file, - line, fnc); - return; - } - - fprintf(fp, "%s:%s %s:%d %s() ", name, d->domain_str, file, line, - fnc); -} - -static void -eina_log_print_prefix_threads_NOcolor_NOfile_func(FILE * fp, - const Eina_Log_Domain * - d, Eina_Log_Level level, - const char *file - __UNUSED__, - const char *fnc, - int line __UNUSED__) -{ - Thread cur; - - DECLARE_LEVEL_NAME(level); - cur = SELF(); - if (IS_OTHER(cur)) { - fprintf(fp, "%s:%s[T:%lu] %s() ", - name, d->domain_str, (unsigned long) cur, fnc); - return; - } - - fprintf(fp, "%s:%s %s() ", name, d->domain_str, fnc); -} - -static void -eina_log_print_prefix_threads_NOcolor_file_NOfunc(FILE * fp, - const Eina_Log_Domain * - d, Eina_Log_Level level, - const char *file, - const char *fnc - __UNUSED__, int line) -{ - Thread cur; - - DECLARE_LEVEL_NAME(level); - cur = SELF(); - if (IS_OTHER(cur)) { - fprintf(fp, "%s:%s[T:%lu] %s:%d ", - name, d->domain_str, (unsigned long) cur, file, - line); - return; - } - - fprintf(fp, "%s:%s %s:%d ", name, d->domain_str, file, line); -} - -/* threads, color */ -static void -eina_log_print_prefix_threads_color_file_func(FILE * fp, - const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, int line) -{ - Thread cur; - - DECLARE_LEVEL_NAME_COLOR(level); - cur = SELF(); - if (IS_OTHER(cur)) { -#ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - color); - fprintf(fp, "%s", name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, ":"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - eina_log_win32_color_get(d-> - domain_str)); - fprintf(fp, "%s[T:", d->name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "[T:"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "%lu", (unsigned long) cur); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "] %s:%d ", file, line); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_INTENSITY | - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "%s()", fnc); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, " "); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s[T:" - EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET "] %s:%d " - EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", - color, name, d->domain_str, (unsigned long) cur, - file, line, fnc); -#endif - return; - } -#ifdef _WIN32 - eina_log_print_prefix_NOthreads_color_file_func(fp, - d, - level, - file, fnc, line); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s %s:%d " - EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", - color, name, d->domain_str, file, line, fnc); -#endif -} - -static void -eina_log_print_prefix_threads_color_NOfile_func(FILE * fp, - const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file - __UNUSED__, - const char *fnc, - int line __UNUSED__) -{ - Thread cur; - - DECLARE_LEVEL_NAME_COLOR(level); - cur = SELF(); - if (IS_OTHER(cur)) { -#ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - color); - fprintf(fp, "%s", name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, ":"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - eina_log_win32_color_get(d-> - domain_str)); - fprintf(fp, "%s[T:", d->name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "[T:"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "%lu", (unsigned long) cur); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_INTENSITY | - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "%s()", fnc); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, " "); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s[T:" - EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET "] " - EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", - color, name, d->domain_str, (unsigned long) cur, - fnc); -#endif - return; - } -#ifdef _WIN32 - eina_log_print_prefix_NOthreads_color_NOfile_func(fp, - d, - level, - file, fnc, line); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s " - EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", - color, name, d->domain_str, fnc); -#endif -} - -static void -eina_log_print_prefix_threads_color_file_NOfunc(FILE * fp, - const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc __UNUSED__, - int line) -{ - Thread cur; - - DECLARE_LEVEL_NAME_COLOR(level); - cur = SELF(); - if (IS_OTHER(cur)) { -#ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - color); - fprintf(fp, "%s", name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, ":"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - eina_log_win32_color_get(d-> - domain_str)); - fprintf(fp, "%s[T:", d->name); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "[T:"); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "%lu", (unsigned long) cur); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE); - fprintf(fp, "] %s:%d ", file, line); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s[T:" - EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET - "] %s:%d ", color, name, d->domain_str, - (unsigned long) cur, file, line); -#endif - return; - } -#ifdef _WIN32 - eina_log_print_prefix_NOthreads_color_file_NOfunc(fp, - d, - level, - file, fnc, line); -#else - fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s %s:%d ", - color, name, d->domain_str, file, line); -#endif -} -#endif /* EFL_HAVE_THREADS */ - -static void (*_eina_log_print_prefix) (FILE * fp, - const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, const char *fnc, - int line) = - eina_log_print_prefix_NOthreads_color_file_func; - -static inline void eina_log_print_prefix_update(void) -{ - if (_disable_file && _disable_function) { - fprintf(stderr, - "ERROR: cannot have " EINA_LOG_ENV_FILE_DISABLE - " and " EINA_LOG_ENV_FUNCTION_DISABLE - " set at the same time, will " - "just disable function.\n"); - _disable_file = 0; - } -#define S(NOthread, NOcolor, NOfile, NOfunc) \ - _eina_log_print_prefix = \ - eina_log_print_prefix_ ## NOthread ## threads_ ## NOcolor ## color_ ## \ - NOfile \ - ## file_ ## NOfunc ## func - -#ifdef EFL_HAVE_THREADS - if (_threads_enabled) { - if (_disable_color) { - if (_disable_file) - S(, NO, NO,); - else if (_disable_function) - S(, NO,, NO); - else - S(, NO,,); - } else { - if (_disable_file) - S(,, NO,); - else if (_disable_function) - S(,,, NO); - else - S(,,,); - } - - return; - } -#endif - - if (_disable_color) { - if (_disable_file) - S(NO, NO, NO,); - else if (_disable_function) - S(NO, NO,, NO); - else - S(NO, NO,,); - } else { - if (_disable_file) - S(NO,, NO,); - else if (_disable_function) - S(NO,,, NO); - else - S(NO,,,); - } - -#undef S -} - -/* - * Creates a colored domain name string. - */ -static const char *eina_log_domain_str_get(const char *name, - const char *color) -{ - const char *d; - - if (color) { - size_t name_len; - size_t color_len; - - name_len = strlen(name); - color_len = strlen(color); - d = malloc(sizeof(char) * - (color_len + name_len + - strlen(EINA_COLOR_RESET) + 1)); - if (!d) - return NULL; - - memcpy((char *) d, color, color_len); - memcpy((char *) (d + color_len), name, name_len); - memcpy((char *) (d + color_len + name_len), - EINA_COLOR_RESET, strlen(EINA_COLOR_RESET)); - ((char *) d)[color_len + name_len + - strlen(EINA_COLOR_RESET)] = '\0'; - } else - d = strdup(name); - - return d; -} - -/* - * Setups a new logging domain to the name and color specified. Note that this - * constructor acts upon an pre-allocated object. - */ -static Eina_Log_Domain *eina_log_domain_new(Eina_Log_Domain * d, - const char *name, - const char *color) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); - - d->level = EINA_LOG_LEVEL_UNKNOWN; - d->deleted = EINA_FALSE; - - if (name) { - if ((color) && (!_disable_color)) - d->domain_str = - eina_log_domain_str_get(name, color); - else - d->domain_str = - eina_log_domain_str_get(name, NULL); - - d->name = strdup(name); - d->namelen = strlen(name); - } else { - d->domain_str = NULL; - d->name = NULL; - d->namelen = 0; - } - - return d; -} - -/* - * Frees internal strings of a log domain, keeping the log domain itself as a - * slot for next domain registers. - */ -static void eina_log_domain_free(Eina_Log_Domain * d) -{ - EINA_SAFETY_ON_NULL_RETURN(d); - - if (d->domain_str) - free((char *) d->domain_str); - - if (d->name) - free((char *) d->name); -} - -/* - * Parses domain levels passed through the env var. - */ -static void eina_log_domain_parse_pendings(void) -{ - const char *start; - - if (!(start = getenv(EINA_LOG_ENV_LEVELS))) - return; - - // name1:level1,name2:level2,name3:level3,... - while (1) { - Eina_Log_Domain_Level_Pending *p; - char *end = NULL; - char *tmp = NULL; - long int level; - - end = strchr(start, ':'); - if (!end) - break; - - // Parse level, keep going if failed - level = strtol((char *) (end + 1), &tmp, 10); - if (tmp == (end + 1)) - goto parse_end; - - // Parse name - p = malloc(sizeof(Eina_Log_Domain_Level_Pending) + end - - start + 1); - if (!p) - break; - - p->namelen = end - start; - memcpy((char *) p->name, start, end - start); - ((char *) p->name)[end - start] = '\0'; - p->level = level; - - _pending_list = - eina_inlist_append(_pending_list, EINA_INLIST_GET(p)); - - parse_end: - start = strchr(tmp, ','); - if (start) - start++; - else - break; - } -} - -static void eina_log_domain_parse_pending_globs(void) -{ - const char *start; - - if (!(start = getenv(EINA_LOG_ENV_LEVELS_GLOB))) - return; - - // name1:level1,name2:level2,name3:level3,... - while (1) { - Eina_Log_Domain_Level_Pending *p; - char *end = NULL; - char *tmp = NULL; - long int level; - - end = strchr(start, ':'); - if (!end) - break; - - // Parse level, keep going if failed - level = strtol((char *) (end + 1), &tmp, 10); - if (tmp == (end + 1)) - goto parse_end; - - // Parse name - p = malloc(sizeof(Eina_Log_Domain_Level_Pending) + end - - start + 1); - if (!p) - break; - - p->namelen = 0; /* not that useful */ - memcpy((char *) p->name, start, end - start); - ((char *) p->name)[end - start] = '\0'; - p->level = level; - - _glob_list = - eina_inlist_append(_glob_list, EINA_INLIST_GET(p)); - - parse_end: - start = strchr(tmp, ','); - if (start) - start++; - else - break; - } -} - -static inline int -eina_log_domain_register_unlocked(const char *name, const char *color) -{ - Eina_Log_Domain_Level_Pending *pending = NULL; - size_t namelen; - unsigned int i; - - for (i = 0; i < _log_domains_count; i++) { - if (_log_domains[i].deleted) { - // Found a flagged slot, free domain_str and replace slot - eina_log_domain_new(&_log_domains[i], name, color); - goto finish_register; - } - } - - if (_log_domains_count >= _log_domains_allocated) { - Eina_Log_Domain *tmp; - size_t size; - - if (!_log_domains) - // special case for init, eina itself will allocate a dozen of domains - size = 24; - else - // grow 8 buckets to minimize reallocs - size = _log_domains_allocated + 8; - - tmp = - realloc(_log_domains, sizeof(Eina_Log_Domain) * size); - - if (tmp) { - // Success! - _log_domains = tmp; - _log_domains_allocated = size; - } else - return -1; - } - // Use an allocated slot - eina_log_domain_new(&_log_domains[i], name, color); - _log_domains_count++; - - finish_register: - namelen = _log_domains[i].namelen; - - EINA_INLIST_FOREACH(_pending_list, pending) { - if ((namelen == pending->namelen) - && (strcmp(pending->name, name) == 0)) { - _log_domains[i].level = pending->level; - _pending_list = - eina_inlist_remove(_pending_list, - EINA_INLIST_GET(pending)); - free(pending); - break; - } - } - - if (_log_domains[i].level == EINA_LOG_LEVEL_UNKNOWN) { - EINA_INLIST_FOREACH(_glob_list, pending) { - if (!fnmatch(pending->name, name, 0)) { - _log_domains[i].level = pending->level; - break; - } - } - } - // Check if level is still UNKNOWN, set it to global - if (_log_domains[i].level == EINA_LOG_LEVEL_UNKNOWN) - _log_domains[i].level = _log_level; - - return i; -} - -static inline Eina_Bool eina_log_term_color_supported(const char *term) -{ - const char *tail; - - if (!term) - return EINA_FALSE; - - tail = term + 1; - switch (term[0]) { - /* list of known to support color terminals, - * take from gentoo's portage. - */ - - case 'x': /* xterm and xterm-color */ - return ((strncmp(tail, "term", sizeof("term") - 1) == 0) && - ((tail[sizeof("term") - 1] == '\0') || - (strcmp(tail + sizeof("term") - 1, "-color") == - 0))); - - case 'E': /* Eterm */ - case 'a': /* aterm */ - case 'k': /* kterm */ - return (strcmp(tail, "term") == 0); - - case 'r': /* xrvt or rxvt-unicode */ - return ((strncmp(tail, "xvt", sizeof("xvt") - 1) == 0) && - ((tail[sizeof("xvt") - 1] == '\0') || - (strcmp(tail + sizeof("xvt") - 1, "-unicode") == - 0))); - - case 's': /* screen */ - return (strcmp(tail, "creen") == 0); - - case 'g': /* gnome */ - return (strcmp(tail, "nome") == 0); - - case 'i': /* interix */ - return (strcmp(tail, "nterix") == 0); - - default: - return EINA_FALSE; - } -} - -static inline void eina_log_domain_unregister_unlocked(int domain) -{ - Eina_Log_Domain *d; - - if ((unsigned int) domain >= _log_domains_count) - return; - - d = &_log_domains[domain]; - eina_log_domain_free(d); - d->deleted = 1; -} - -static inline void -eina_log_print_unlocked(int domain, - Eina_Log_Level level, - const char *file, - const char *fnc, - int line, const char *fmt, va_list args) -{ - Eina_Log_Domain *d; - -#ifdef EINA_SAFETY_CHECKS - if (EINA_UNLIKELY((unsigned int) domain >= _log_domains_count) || - EINA_UNLIKELY(domain < 0)) { - if (file && fnc && fmt) - fprintf(stderr, - "CRI: %s:%d %s() eina_log_print() unknown domain %d, original message format '%s'\n", - file, line, fnc, domain, fmt); - else - fprintf(stderr, - "CRI: eina_log_print() unknown domain %d, original message format '%s'\n", - domain, fmt ? fmt : ""); - - if (_abort_on_critical) - abort(); - - return; - } -#endif - d = _log_domains + domain; -#ifdef EINA_SAFETY_CHECKS - if (EINA_UNLIKELY(d->deleted)) { - fprintf(stderr, - "ERR: eina_log_print() domain %d is deleted\n", - domain); - return; - } -#endif - - if (level > d->level) - return; - -#ifdef _WIN32 - { - char *wfmt; - char *tmp; - - wfmt = strdup(fmt); - if (!wfmt) { - fprintf(stderr, - "ERR: %s: can not allocate memory\n", - __FUNCTION__); - return; - } - - tmp = wfmt; - while (strchr(tmp, "%")) { - tmp++; - if (*tmp == 'z') - *tmp = 'I'; - } - _print_cb(d, level, file, fnc, line, wfmt, _print_cb_data, - args); - free(wfmt); - } -#else - _print_cb(d, level, file, fnc, line, fmt, _print_cb_data, args); -#endif - - if (EINA_UNLIKELY(_abort_on_critical) && - EINA_UNLIKELY(level <= _abort_level_on_critical)) - abort(); -} - -/** - * @endcond - */ - - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the log module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the log module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - * - * @warning Not-MT: just call this function from main thread! The - * place where this function was called the first time is - * considered the main thread. - */ -Eina_Bool eina_log_init(void) -{ - const char *level, *tmp; - int color_disable; - - assert((sizeof(_names) / sizeof(_names[0])) == EINA_LOG_LEVELS); - - if ((tmp = getenv(EINA_LOG_ENV_COLOR_DISABLE))) - color_disable = atoi(tmp); - else - color_disable = -1; - - /* Check if color is explicitly disabled */ - if (color_disable == 1) - _disable_color = EINA_TRUE; - -#ifndef _WIN32 - /* color was not explicitly disabled or enabled, guess it */ - else if (color_disable == -1) { - if (!eina_log_term_color_supported(getenv("TERM"))) - _disable_color = EINA_TRUE; - else { - /* if not a terminal, but redirected to a file, disable color */ - int fd; - - if (_print_cb == eina_log_print_cb_stderr) - fd = STDERR_FILENO; - else if (_print_cb == eina_log_print_cb_stdout) - fd = STDOUT_FILENO; - else - fd = -1; - - if ((fd >= 0) && (!isatty(fd))) - _disable_color = EINA_TRUE; - } - } -#endif - - if ((tmp = getenv(EINA_LOG_ENV_FILE_DISABLE)) && (atoi(tmp) == 1)) - _disable_file = EINA_TRUE; - - if ((tmp = getenv(EINA_LOG_ENV_FUNCTION_DISABLE)) - && (atoi(tmp) == 1)) - _disable_function = EINA_TRUE; - - if ((tmp = getenv(EINA_LOG_ENV_ABORT)) && (atoi(tmp) == 1)) - _abort_on_critical = EINA_TRUE; - - if ((tmp = getenv(EINA_LOG_ENV_ABORT_LEVEL))) - _abort_level_on_critical = atoi(tmp); - - eina_log_print_prefix_update(); - - // Global log level - if ((level = getenv(EINA_LOG_ENV_LEVEL))) - _log_level = atoi(level); - - // Register UNKNOWN domain, the default logger - EINA_LOG_DOMAIN_GLOBAL = eina_log_domain_register("", NULL); - - if (EINA_LOG_DOMAIN_GLOBAL < 0) { - fprintf(stderr, - "Failed to create global logging domain.\n"); - return EINA_FALSE; - } - // Parse pending domains passed through EINA_LOG_LEVELS_GLOB - eina_log_domain_parse_pending_globs(); - - // Parse pending domains passed through EINA_LOG_LEVELS - eina_log_domain_parse_pendings(); - - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the log module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the log module set up by - * eina_log_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - * - * @warning Not-MT: just call this function from main thread! The - * place where eina_log_init() (eina_init()) was called the - * first time is considered the main thread. - */ -Eina_Bool eina_log_shutdown(void) -{ - Eina_Inlist *tmp; - - while (_log_domains_count--) { - if (_log_domains[_log_domains_count].deleted) - continue; - - eina_log_domain_free(&_log_domains[_log_domains_count]); - } - - free(_log_domains); - - _log_domains = NULL; - _log_domains_count = 0; - _log_domains_allocated = 0; - - while (_glob_list) { - tmp = _glob_list; - _glob_list = _glob_list->next; - free(tmp); - } - - while (_pending_list) { - tmp = _pending_list; - _pending_list = _pending_list->next; - free(tmp); - } - - return EINA_TRUE; -} - -#ifdef EFL_HAVE_THREADS - -/** - * @internal - * @brief Activate the log mutex. - * - * This function activate the mutex in the eina log module. It is called by - * eina_threads_init(). - * - * @see eina_threads_init() - */ -void eina_log_threads_init(void) -{ - _main_thread = SELF(); - if (INIT()) - _threads_enabled = EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the log mutex. - * - * This function shuts down the mutex in the log module. - * It is called by eina_threads_shutdown(). - * - * @see eina_threads_shutdown() - */ -void eina_log_threads_shutdown(void) -{ - CHECK_MAIN(); - SHUTDOWN(); - _threads_enabled = EINA_FALSE; -} - -#endif - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Log_Group Log - * - * @brief Full-featured logging system. - * - * Eina provides eina_log_print(), a standard function to manage all - * logging messages. This function may be called directly or using the - * helper macros such as EINA_LOG_DBG(), EINA_LOG_ERR() or those that - * take a specific domain as argument EINA_LOG_DOM_DBG(), - * EINA_LOG_DOM_ERR(). Internally, eina_log_print() will call the - * function defined with eina_log_print_cb_set(), that defaults to - * eina_log_print_cb_stderr(), but may be changed to do whatever you - * need, such as networking or syslog logging. - * - * The logging system is thread safe once initialized with - * eina_log_threads_enable(). The thread that calls this function - * first is considered "main thread" and other threads will have their - * thread id (pthread_self()) printed in the log message so it is easy - * to detect from where it is coming. - * - * Log domains is the Eina way to differentiate messages. There might - * be different domains to represent different modules, different - * feature-set, different categories and so on. Filtering can be - * applied to domain names by means of @c EINA_LOG_LEVELS environment - * variable or eina_log_domain_level_set(). - * - * The different logging levels serve to customize the amount of - * debugging one want to take and may be used to automatically call - * abort() once some given level message is printed. This is - * controlled by environment variable @c EINA_LOG_ABORT and the level - * to be considered critical with @c EINA_LOG_ABORT_LEVEL. These can - * be changed with eina_log_abort_on_critical_set() and - * eina_log_abort_on_critical_level_set(). - * - * The default maximum level to print is defined by environment - * variable @c EINA_LOG_LEVEL, but may be set per-domain with @c - * EINA_LOG_LEVELS. It will default to #EINA_LOG_ERR. This can be - * changed with eina_log_level_set(). - * - * To use the log system Eina must be initialized with eina_init() and - * later shut down with eina_shutdown(). Here is a straightforward - * example: - * - * @code - * #include <stdlib.h> - * #include <stdio.h> - * - * #include <eina_log.h> - * - * void test_warn(void) - * { - * EINA_LOG_WARN("Here is a warning message"); - * } - * - * int main(void) - * { - * if (!eina_init()) - * { - * printf("log during the initialization of Eina_Log module\n"); - * return EXIT_FAILURE; - * } - * - * test_warn(); - * - * eina_shutdown(); - * - * return EXIT_SUCCESS; - * } - * @endcode - * - * Compile this code with the following command: - * - * @code - * gcc -Wall -o test_Eina_Log test_eina.c `pkg-config --cflags --libs eina` - * @endcode - * - * Now execute the program with: - * - * @code - * EINA_LOG_LEVEL=2 ./test_eina_log - * @endcode - * - * You should see a message displayed in the terminal. - * - * For more information, you can look at the @ref tutorial_log_page. - * - * @{ - */ - - -/** - * @cond LOCAL - */ - -EAPI int EINA_LOG_DOMAIN_GLOBAL = 0; - -/** - * @endcond - */ - - -/** - * Enable logging module to handle threads. - * - * There is no disable option on purpose, if it is enabled, there is - * no way back until you call the last eina_shutdown(). - * - * There is no function to retrieve if threads are enabled as one is - * not supposed to know this from outside. - * - * After this call is executed at least once, if Eina was compiled - * with threads support then logging will lock around debug messages - * and threads that are not the main thread will have its identifier - * printed. - * - * The main thread is considered the thread where the first - * eina_init() was called. - */ -EAPI void eina_log_threads_enable(void) -{ -#ifdef EFL_HAVE_THREADS - _threads_enabled = 1; - eina_log_print_prefix_update(); -#endif -} - -/** - * Sets logging method to use. - * - * @param cb The callback to call when printing a log. - * @param data The data to pass to the callback. - * - * By default, eina_log_print_cb_stderr() is used. - * - * @note MT: safe to call from any thread. - * - * @note MT: given function @a cb will be called protected by mutex. - * This means you're safe from other calls but you should never - * call eina_log_print(), directly or indirectly. - */ -EAPI void eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data) -{ - LOG_LOCK(); - _print_cb = cb; - _print_cb_data = data; - eina_log_print_prefix_update(); - LOG_UNLOCK(); -} - -/** - * @brief Set the default log level. - * - * @param level The log level. - * - * This function sets the log level @p level. It is used in - * eina_log_print(). - * - * @note this is initially set to envvar EINA_LOG_LEVEL by eina_init(). - * - * @see eina_log_level_get() - */ -EAPI void eina_log_level_set(int level) -{ - _log_level = level; - if (EINA_LIKELY((EINA_LOG_DOMAIN_GLOBAL >= 0) && - ((unsigned int) EINA_LOG_DOMAIN_GLOBAL < - _log_domains_count))) - _log_domains[EINA_LOG_DOMAIN_GLOBAL].level = level; -} - -/** - * @brief Get the default log level. - * - * @return the log level that limits eina_log_print(). - * - * @see eina_log_level_set() - */ -EAPI int eina_log_level_get(void) -{ - return _log_level; -} - -/** - * Checks if current thread is the main thread. - * - * @return #EINA_TRUE if threads were enabled and the current thread - * is the one that called eina_log_threads_init(). If there is - * no thread support (compiled with --disable-pthreads) or - * they were not enabled, then #EINA_TRUE is also - * returned. The only case where #EINA_FALSE is returned is - * when threads were successfully enabled but the current - * thread is not the main (one that called - * eina_log_threads_init()). - */ -EAPI Eina_Bool eina_log_main_thread_check(void) -{ -#ifdef EFL_HAVE_THREADS - return ((!_threads_enabled) || IS_MAIN(SELF())); -#else - return EINA_TRUE; -#endif -} - -/** - * @brief Set if color logging should be disabled. - * - * @param disabled if #EINA_TRUE, color logging should be disabled. - * - * @note this is initially set to envvar EINA_LOG_COLOR_DISABLE by eina_init(). - * - * @see eina_log_color_disable_get() - */ -EAPI void eina_log_color_disable_set(Eina_Bool disabled) -{ - _disable_color = disabled; -} - -/** - * @brief Get if color logging should be disabled. - * - * @return if #EINA_TRUE, color logging should be disabled. - * - * @see eina_log_color_disable_set() - */ -EAPI Eina_Bool eina_log_color_disable_get(void) -{ - return _disable_color; -} - -/** - * @brief Set if originating file name logging should be disabled. - * - * @param disabled if #EINA_TRUE, file name logging should be disabled. - * - * @note this is initially set to envvar EINA_LOG_FILE_DISABLE by eina_init(). - * - * @see eina_log_file_disable_get() - */ -EAPI void eina_log_file_disable_set(Eina_Bool disabled) -{ - _disable_file = disabled; -} - -/** - * @brief Get if originating file name logging should be disabled. - * - * @return if #EINA_TRUE, file name logging should be disabled. - * - * @see eina_log_file_disable_set() - */ -EAPI Eina_Bool eina_log_file_disable_get(void) -{ - return _disable_file; -} - -/** - * @brief Set if originating function name logging should be disabled. - * - * @param disabled if #EINA_TRUE, function name logging should be disabled. - * - * @note this is initially set to envvar EINA_LOG_FUNCTION_DISABLE by - * eina_init(). - * - * @see eina_log_function_disable_get() - */ -EAPI void eina_log_function_disable_set(Eina_Bool disabled) -{ - _disable_function = disabled; -} - -/** - * @brief Get if originating function name logging should be disabled. - * - * @return if #EINA_TRUE, function name logging should be disabled. - * - * @see eina_log_function_disable_set() - */ -EAPI Eina_Bool eina_log_function_disable_get(void) -{ - return _disable_function; -} - -/** - * @brief Set if critical messages should abort the program. - * - * @param abort_on_critical if #EINA_TRUE, messages with level equal - * or smaller than eina_log_abort_on_critical_level_get() will - * abort the program. - * - * @note this is initially set to envvar EINA_LOG_ABORT by - * eina_init(). - * - * @see eina_log_abort_on_critical_get() - * @see eina_log_abort_on_critical_level_set() - */ -EAPI void eina_log_abort_on_critical_set(Eina_Bool abort_on_critical) -{ - _abort_on_critical = abort_on_critical; -} - -/** - * @brief Get if critical messages should abort the program. - * - * @return if #EINA_TRUE, any messages with level equal or smaller - * than eina_log_abort_on_critical_level_get() will abort the - * program. - * - * @see eina_log_abort_on_critical_set() - * @see eina_log_abort_on_critical_level_set() - */ -EAPI Eina_Bool eina_log_abort_on_critical_get(void) -{ - return _abort_on_critical; -} - -/** - * @brief Set level that triggers abort if abort-on-critical is set. - * - * @param critical_level levels equal or smaller than the given value - * will trigger program abortion if - * eina_log_abort_on_critical_get() returns #EINA_TRUE. - * - * @note this is initially set to envvar EINA_LOG_ABORT_LEVEL by - * eina_init(). - * - * @see eina_log_abort_on_critical_level_get() - * @see eina_log_abort_on_critical_get() - */ -EAPI void eina_log_abort_on_critical_level_set(int critical_level) -{ - _abort_level_on_critical = critical_level; -} - -/** - * @brief Get level that triggers abort if abort-on-critical is set. - * - * @return critical level equal or smaller than value will trigger - * program abortion if eina_log_abort_on_critical_get() returns - * #EINA_TRUE. - * - * @see eina_log_abort_on_critical_level_set() - * @see eina_log_abort_on_critical_get() - */ -EAPI int eina_log_abort_on_critical_level_get(void) -{ - return _abort_level_on_critical; -} - -/** - * @param name Domain name - * @param color Color of the domain name - * - * @return Domain index that will be used as the DOMAIN parameter on log - * macros. A negative return value means an log occurred. - * - * @note MT: safe to call from any thread. - */ -EAPI int eina_log_domain_register(const char *name, const char *color) -{ - int r; - - EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1); - - LOG_LOCK(); - r = eina_log_domain_register_unlocked(name, color); - LOG_UNLOCK(); - return r; -} - -/** - * Forget about a logging domain registered by eina_log_domain_register() - * - * @param domain domain identifier as reported by eina_log_domain_register(), - * must be >= 0. - * - * @note MT: safe to call from any thread. - */ -EAPI void eina_log_domain_unregister(int domain) -{ - EINA_SAFETY_ON_FALSE_RETURN(domain >= 0); - LOG_LOCK(); - eina_log_domain_unregister_unlocked(domain); - LOG_UNLOCK(); -} - -/** - * Set the domain level given its name. - * - * This call has the same effect as setting - * EINA_LOG_LEVELS=<@p domain_name>:<@p level> - * - * @param domain_name domain name to change the level. It may be of a - * still not registered domain. If the domain is not registered - * yet, it will be saved as a pending set and applied upon - * registration. - * @param level level to use to limit eina_log_print() for given domain. - */ -EAPI void eina_log_domain_level_set(const char *domain_name, int level) -{ - Eina_Log_Domain_Level_Pending *pending; - size_t namelen; - unsigned int i; - - EINA_SAFETY_ON_NULL_RETURN(domain_name); - - namelen = strlen(domain_name); - - for (i = 0; i < _log_domains_count; i++) { - if (_log_domains[i].deleted) - continue; - - if ((namelen != _log_domains[i].namelen) || - (strcmp(_log_domains[i].name, domain_name) != 0)) - continue; - - _log_domains[i].level = level; - return; - } - - EINA_INLIST_FOREACH(_pending_list, pending) { - if ((namelen == pending->namelen) && - (strcmp(pending->name, domain_name) == 0)) { - pending->level = level; - return; - } - } - - pending = - malloc(sizeof(Eina_Log_Domain_Level_Pending) + namelen + 1); - if (!pending) - return; - - pending->level = level; - pending->namelen = namelen; - memcpy(pending->name, domain_name, namelen + 1); - - _pending_list = - eina_inlist_append(_pending_list, EINA_INLIST_GET(pending)); -} - -/** - * Get the domain level given its name. - * - * @param domain_name domain name to retrieve the level. It may be of - * a still not registered domain. If the domain is not - * registered yet, but there is a pending value, either from - * eina_log_domain_level_set(),EINA_LOG_LEVELS environment - * variable or from EINA_LOG_LEVELS_GLOB, these are - * returned. If nothing else was found, then the global/default - * level (eina_log_level_get()) is returned. - * - * @return level to use to limit eina_log_print() for given - * domain. On error (@p domain_name == NULL), - * EINA_LOG_LEVEL_UNKNOWN is returned. - * - * @see eina_log_domain_level_set() - * @see eina_log_domain_registered_level_get() - */ -EAPI int eina_log_domain_level_get(const char *domain_name) -{ - Eina_Log_Domain_Level_Pending *pending; - size_t namelen; - unsigned int i; - - EINA_SAFETY_ON_NULL_RETURN_VAL(domain_name, - EINA_LOG_LEVEL_UNKNOWN); - - namelen = strlen(domain_name); - - for (i = 0; i < _log_domains_count; i++) { - if (_log_domains[i].deleted) - continue; - - if ((namelen != _log_domains[i].namelen) || - (strcmp(_log_domains[i].name, domain_name) != 0)) - continue; - - return _log_domains[i].level; - } - - EINA_INLIST_FOREACH(_pending_list, pending) { - if ((namelen == pending->namelen) && - (strcmp(pending->name, domain_name) == 0)) - return pending->level; - } - - EINA_INLIST_FOREACH(_glob_list, pending) { - if (!fnmatch(pending->name, domain_name, 0)) - return pending->level; - } - - return _log_level; -} - -/** - * Get the domain level given its identifier. - * - * @param domain identifier, so it must be previously registered with - * eina_log_domain_register(). It's a much faster version of - * eina_log_domain_level_get(), but relies on domain being - * present. - * - * @return level to use to limit eina_log_print() for given domain. On - * error EINA_LOG_LEVEL_UNKNOWN is returned. - */ -EAPI int eina_log_domain_registered_level_get(int domain) -{ - EINA_SAFETY_ON_FALSE_RETURN_VAL(domain >= 0, - EINA_LOG_LEVEL_UNKNOWN); - EINA_SAFETY_ON_FALSE_RETURN_VAL((unsigned int) domain < - _log_domains_count, - EINA_LOG_LEVEL_UNKNOWN); - EINA_SAFETY_ON_TRUE_RETURN_VAL(_log_domains[domain].deleted, - EINA_LOG_LEVEL_UNKNOWN); - return _log_domains[domain].level; -} - -/** - * Default logging method, this will output to standard error stream. - * - * This method will colorize output based on domain provided color and - * message logging level. - * - * To disable color, set environment variable - * EINA_LOG_COLOR_DISABLE=1. To enable color, even if directing to a - * file or when using a non-supported color terminal, use - * EINA_LOG_COLOR_DISABLE=0. If EINA_LOG_COLOR_DISABLE is unset (or - * -1), then Eina will disable color if terminal ($TERM) is - * unsupported or if redirecting to a file. - - . Similarly, to disable file and line - * information, set EINA_LOG_FILE_DISABLE=1 or - * EINA_LOG_FUNCTION_DISABLE=1 to avoid function name in output. It is - * not acceptable to have both EINA_LOG_FILE_DISABLE and - * EINA_LOG_FUNCTION_DISABLE at the same time, in this case just - * EINA_LOG_FUNCTION_DISABLE will be considered and file information - * will be printed anyways. - * - * @note MT: if threads are enabled, this function is called within locks. - * @note MT: Threads different from main thread will have thread id - * appended to domain name. - */ -EAPI void -eina_log_print_cb_stderr(const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, - int line, - const char *fmt, - __UNUSED__ void *data, va_list args) -{ - _eina_log_print_prefix(stderr, d, level, file, fnc, line); - vfprintf(stderr, fmt, args); - putc('\n', stderr); -} - -/** - * Alternative logging method, this will output to standard output stream. - * - * @param d The domain. - * @param level The level. - * @param file The file which is logged. - * @param fnc The function which is logged. - * @param line The line which is logged. - * @param fmt The ouptut format to use. - * @param data Not used. - * @param args The arguments needed by the format. - * - * This method will colorize output based on domain provided color and - * message logging level. To disable color, set environment variable - * EINA_LOG_COLOR_DISABLE=1. Similarly, to disable file and line - * information, set EINA_LOG_FILE_DISABLE=1 or - * EINA_LOG_FUNCTION_DISABLE=1 to avoid function name in output. It is - * not acceptable to have both EINA_LOG_FILE_DISABLE and - * EINA_LOG_FUNCTION_DISABLE at the same time, in this case just - * EINA_LOG_FUNCTION_DISABLE will be considered and file information - * will be printed anyways. - * - * @note MT: if threads are enabled, this function is called within locks. - * @note MT: Threads different from main thread will have thread id - * appended to domain name. - */ -EAPI void -eina_log_print_cb_stdout(const Eina_Log_Domain * d, - Eina_Log_Level level, - const char *file, - const char *fnc, - int line, - const char *fmt, - __UNUSED__ void *data, va_list args) -{ - _eina_log_print_prefix(stdout, d, level, file, fnc, line); - vprintf(fmt, args); - putchar('\n'); -} - -/** - * Alternative logging method, this will output to given file stream. - * - * @param d The domain. - * @param level Not used. - * @param file The file which is logged. - * @param fnc The function which is logged. - * @param line The line which is logged. - * @param fmt The ouptut format to use. - * @param data The file which will store the output (as a FILE *). - * @param args The arguments needed by the format. - * - * This method will never output color. - * - * @note MT: if threads are enabled, this function is called within locks. - * @note MT: Threads different from main thread will have thread id - * appended to domain name. - */ -EAPI void -eina_log_print_cb_file(const Eina_Log_Domain * d, - __UNUSED__ Eina_Log_Level level, - const char *file, - const char *fnc, - int line, const char *fmt, void *data, va_list args) -{ - FILE *f = data; -#ifdef EFL_HAVE_THREADS - if (_threads_enabled) { - Thread cur; - - cur = SELF(); - if (IS_OTHER(cur)) { - fprintf(f, "%s[T:%lu] %s:%d %s() ", d->name, - (unsigned long) cur, file, line, fnc); - goto end; - } - } -#endif - fprintf(f, "%s %s:%d %s() ", d->name, file, line, fnc); -#ifdef EFL_HAVE_THREADS - end: -#endif - vfprintf(f, fmt, args); - putc('\n', f); -} - -/** - * Print out log message using given domain and level. - * - * @note Usually you'll not use this function directly but the helper - * macros EINA_LOG(), EINA_LOG_DOM_CRIT(), EINA_LOG_CRIT() and - * so on. See eina_log.h - * - * @param domain logging domain to use or @c EINA_LOG_DOMAIN_GLOBAL if - * you registered none. It is recommended that modules and - * applications have their own logging domain. - * @param level message level, those with level greater than user - * specified value (eina_log_level_set() or environment - * variables EINA_LOG_LEVEL, EINA_LOG_LEVELS) will be ignored. - * @param file filename that originated the call, must @b not be @c NULL. - * @param fnc function that originated the call, must @b not be @c NULL. - * @param line originating line in @a file. - * @param fmt printf-like format to use. Should not provide trailing - * '\n' as it is automatically included. - * - * @note MT: this function may be called from different threads if - * eina_log_threads_enable() was called before. - */ -EAPI void -eina_log_print(int domain, Eina_Log_Level level, const char *file, - const char *fnc, int line, const char *fmt, ...) -{ - va_list args; - -#ifdef EINA_SAFETY_CHECKS - if (EINA_UNLIKELY(!file)) { - fputs("ERR: eina_log_print() file == NULL\n", stderr); - return; - } - - if (EINA_UNLIKELY(!fnc)) { - fputs("ERR: eina_log_print() fnc == NULL\n", stderr); - return; - } - - if (EINA_UNLIKELY(!fmt)) { - fputs("ERR: eina_log_print() fmt == NULL\n", stderr); - return; - } -#endif - va_start(args, fmt); - LOG_LOCK(); - eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args); - LOG_UNLOCK(); - va_end(args); -} - -/** - * Print out log message using given domain and level. - * - * @note Usually you'll not use this function directly but the helper - * macros EINA_LOG(), EINA_LOG_DOM_CRIT(), EINA_LOG_CRIT() and - * so on. See eina_log.h - * - * @param domain logging domain to use or @c EINA_LOG_DOMAIN_GLOBAL if - * you registered none. It is recommended that modules and - * applications have their own logging domain. - * @param level message level, those with level greater than user - * specified value (eina_log_level_set() or environment - * variables EINA_LOG_LEVEL, EINA_LOG_LEVELS) will be ignored. - * @param file filename that originated the call, must @b not be @c NULL. - * @param fnc function that originated the call, must @b not be @c NULL. - * @param line originating line in @a file. - * @param fmt printf-like format to use. Should not provide trailing - * '\n' as it is automatically included. - * @param args the arguments needed by the format. - * - * @note MT: this function may be called from different threads if - * eina_log_threads_enable() was called before. - * - * @see eina_log_print() - */ -EAPI void -eina_log_vprint(int domain, Eina_Log_Level level, const char *file, - const char *fnc, int line, const char *fmt, va_list args) -{ -#ifdef EINA_SAFETY_CHECKS - if (EINA_UNLIKELY(!file)) { - fputs("ERR: eina_log_print() file == NULL\n", stderr); - return; - } - - if (EINA_UNLIKELY(!fnc)) { - fputs("ERR: eina_log_print() fnc == NULL\n", stderr); - return; - } - - if (EINA_UNLIKELY(!fmt)) { - fputs("ERR: eina_log_print() fmt == NULL\n", stderr); - return; - } -#endif - LOG_LOCK(); - eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args); - LOG_UNLOCK(); -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_magic.c b/tests/suite/ecore/src/lib/eina_magic.c deleted file mode 100644 index 266c1474d8..0000000000 --- a/tests/suite/ecore/src/lib/eina_magic.c +++ /dev/null @@ -1,474 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_error.h" -#include "eina_log.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_magic.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -typedef struct _Eina_Magic_String Eina_Magic_String; -struct _Eina_Magic_String { - Eina_Magic magic; - Eina_Bool string_allocated; - const char *string; -}; - -static int _eina_magic_string_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_magic_string_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_magic_string_log_dom, __VA_ARGS__) - -static Eina_Magic_String *_eina_magic_strings = NULL; -static size_t _eina_magic_strings_count = 0; -static size_t _eina_magic_strings_allocated = 0; -static Eina_Bool _eina_magic_strings_dirty = 0; - -static int _eina_magic_strings_sort_cmp(const void *p1, const void *p2) -{ - const Eina_Magic_String *a = p1, *b = p2; - return a->magic - b->magic; -} - -static int _eina_magic_strings_find_cmp(const void *p1, const void *p2) -{ - Eina_Magic a = (long) p1; - const Eina_Magic_String *b = p2; - return a - b->magic; -} - -static Eina_Magic_String *_eina_magic_strings_alloc(void) -{ - size_t idx; - - if (_eina_magic_strings_count == _eina_magic_strings_allocated) { - void *tmp; - size_t size; - - if (EINA_UNLIKELY(_eina_magic_strings_allocated == 0)) - size = 48; - else - size = _eina_magic_strings_allocated + 16; - - tmp = - realloc(_eina_magic_strings, - sizeof(Eina_Magic_String) * size); - if (!tmp) { -#ifdef _WIN32 - ERR("could not realloc magic_strings from %Iu to %Iu buckets.", -#else - ERR("could not realloc magic_strings from %zu to %zu buckets.", -#endif - _eina_magic_strings_allocated, size); - return NULL; - } - - _eina_magic_strings = tmp; - _eina_magic_strings_allocated = size; - } - - idx = _eina_magic_strings_count; - _eina_magic_strings_count++; - return _eina_magic_strings + idx; -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the magic string module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the magic string module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_magic_string_init(void) -{ - _eina_magic_string_log_dom = eina_log_domain_register - ("eina_magic_string", EINA_LOG_COLOR_DEFAULT); - if (_eina_magic_string_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_magic_string"); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the magic string module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the magic string module set up by - * eina_magic string_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_magic_string_shutdown(void) -{ - Eina_Magic_String *ems, *ems_end; - - ems = _eina_magic_strings; - ems_end = ems + _eina_magic_strings_count; - - for (; ems < ems_end; ems++) - if (ems->string_allocated) - free((char *) ems->string); - - free(_eina_magic_strings); - _eina_magic_strings = NULL; - _eina_magic_strings_count = 0; - _eina_magic_strings_allocated = 0; - - eina_log_domain_unregister(_eina_magic_string_log_dom); - _eina_magic_string_log_dom = -1; - - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Magic_Group Magic - * - * @brief These functions provide runtime type-checking (magic checks) - * management for projects. - * - * C is a weak statically typed language, in other words, it will just - * check for types during compile time and any cast will make the - * compiler believe the type is correct. - * - * In real world projects we often need to deal with casts, either - * explicit or implicit by means of @c void*. We also need to resort - * to casts when doing inheritance in C, as seen in the example below: - * - * @code - * struct base { - * int id; - * char *name; - * }; - * int base_id_get(struct base *ptr) { - * return ptr->id; - * } - * - * struct subtype { - * struct base base; - * time_t date; - * }; - * @endcode - * - * It is perfectly valid to use @c {struct subtype} blobs for functions - * that expect @c {struct base}, since the fields will have the same - * offset (as base member is the first, at offset 0). We could give - * the functions the @c {&subtype->base} and avoid the cast, but often - * we just cast. - * - * In any case, we might be safe and check if the given pointer is - * actually of the expected type. We can do so by using eina_magic, - * that is nothing more than attaching an unique type identifier to - * the members and check for it elsewhere. - * - * @code - * #define BASE_MAGIC 0x12345 - * #define SUBTYPE_MAGIC 0x3333 - * struct base { - * int id; - * char *name; - * EINA_MAGIC; - * }; - * int base_id_get(struct base *ptr) { - * if (!EINA_MAGIC_CHECK(ptr, BASE_MAGIC)) { - * EINA_MAGIC_FAIL(ptr, BASE_MAGIC); - * return -1; - * } - * return ptr->id; - * } - * void base_free(struct base *ptr) { - * if (!EINA_MAGIC_CHECK(ptr, BASE_MAGIC)) { - * EINA_MAGIC_FAIL(ptr, BASE_MAGIC); - * return; - * } - * EINA_MAGIC_SET(ptr, EINA_MAGIC_NONE); - * free(ptr->name); - * free(ptr); - * } - * struct base *base_new(int id, const char *name) { - * struct base *ptr = malloc(sizeof(struct base)); - * EINA_MAGIC_SET(ptr, BASE_MAGIC); - * ptr->id = id; - * ptr->name = strdup(name); - * } - * - * struct subtype { - * struct base base; - * EINA_MAGIC; - * time_t date; - * }; - * - * int my_init(void) { - * eina_init(); - * eina_magic_string_set(BASE_MAGIC, "base type"); - * eina_magic_string_set(SUBTYPE_MAGIC, "subtype"); - * } - * @endcode - * - * This code also shows that it is a good practice to set magic to - * #EINA_MAGIC_NONE before freeing pointer. Sometimes the pointers are - * in pages that are still live in memory, so kernel will not send - * SEGV signal to the process and it may go unnoticed that you're - * using already freed pointers. By setting them to #EINA_MAGIC_NONE - * you avoid using the bogus pointer any further and gets a nice error - * message. - * - * @{ - */ - -/** - * @brief Return the string associated to the given magic identifier. - * - * @param magic The magic identifier. - * @return The string associated to the identifier. - * - * This function returns the string associated to @p magic. If none - * are found, the this function still returns non @c NULL, in this - * case an identifier such as "(none)", "(undefined)" or - * "(unknown)". The returned value must not be freed. - * - * The following identifiers may be returned whenever magic is - * invalid, with their meanings: - * - * - (none): no magic was registered exists at all. - * - (undefined): magic was registered and found, but no string associated. - * - (unknown): magic was not found in the registry. - */ -EAPI const char *eina_magic_string_get(Eina_Magic magic) -{ - Eina_Magic_String *ems; - - if (!_eina_magic_strings) - return "(none)"; - - if (_eina_magic_strings_dirty) { - qsort(_eina_magic_strings, _eina_magic_strings_count, - sizeof(Eina_Magic_String), - _eina_magic_strings_sort_cmp); - _eina_magic_strings_dirty = 0; - } - - ems = bsearch((void *) (long) magic, _eina_magic_strings, - _eina_magic_strings_count, sizeof(Eina_Magic_String), - _eina_magic_strings_find_cmp); - if (ems) - return ems->string ? ems->string : "(undefined)"; - - return "(unknown)"; -} - -/** - * @brief Set the string associated to the given magic identifier. - * - * @param magic The magic identifier. - * @param magic_name The string associated to the identifier, must not - * be @c NULL. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets the string @p magic_name to @p magic. It is not - * checked if number or string are already set, then you might end - * with duplicates in that case. - * - * @see eina_magic_string_static_set() - */ -EAPI Eina_Bool -eina_magic_string_set(Eina_Magic magic, const char *magic_name) -{ - Eina_Magic_String *ems; - - EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE); - - ems = _eina_magic_strings_alloc(); - if (!ems) - return EINA_FALSE; - - ems->magic = magic; - ems->string_allocated = EINA_TRUE; - ems->string = strdup(magic_name); - if (!ems->string) { - ERR("could not allocate string '%s'", magic_name); - _eina_magic_strings_count--; - return EINA_FALSE; - } - - _eina_magic_strings_dirty = 1; - return EINA_TRUE; -} - -/** - * @brief Set the string associated to the given magic identifier. - * - * @param magic The magic identifier. - * @param magic_name The string associated to the identifier, must not be - * @c NULL, it will not be duplcated, just referenced thus it must - * be live during magic number usage. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets the string @p magic_name to @p magic. It is not - * checked if number or string are already set, then you might end - * with duplicates in that case. - * - * @see eina_magic_string_set() - */ -EAPI Eina_Bool -eina_magic_string_static_set(Eina_Magic magic, const char *magic_name) -{ - Eina_Magic_String *ems; - - EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE); - - ems = _eina_magic_strings_alloc(); - if (!ems) - return EINA_FALSE; - - ems->magic = magic; - ems->string_allocated = EINA_FALSE; - ems->string = magic_name; - - _eina_magic_strings_dirty = 1; - return EINA_TRUE; -} - -#ifdef eina_magic_fail -#undef eina_magic_fail -#endif - -/** - * @brief Display a message or abort is a magic check failed. - * - * @param d The checked data pointer. - * @param m The magic identifer to check. - * @param req_m The requested magic identifier to check. - * @param file The file in which the magic check failed. - * @param fnc The function in which the magic check failed. - * @param line The line at which the magic check failed. - * - * This function displays an error message if a magic check has - * failed, using the following logic in the following order: - * @li If @p d is @c NULL, a message warns about a @c NULL pointer. - * @li Otherwise, if @p m is equal to #EINA_MAGIC_NONE, a message - * warns about a handle that was already freed. - * @li Otherwise, if @p m is equal to @p req_m, a message warns about - * a handle that is of wrong type. - * @li Otherwise, a message warns you about ab-using that function... - * - * If the environment variable EINA_ERROR_ABORT is set, abort() is - * called and the program stops. It is useful for debugging programs - * with gdb. - */ -EAPI void -eina_magic_fail(void *d, - Eina_Magic m, - Eina_Magic req_m, - const char *file, const char *fnc, int line) -{ - if (!d) - eina_log_print(EINA_LOG_DOMAIN_GLOBAL, - EINA_LOG_LEVEL_CRITICAL, file, fnc, line, - "*** Eina Magic Check Failed !!!\n" - " Input handle pointer is NULL !\n" - "*** NAUGHTY PROGRAMMER!!!\n" - "*** SPANK SPANK SPANK!!!\n" - "*** Now go fix your code. Tut tut tut!\n" - "\n"); - else if (m == EINA_MAGIC_NONE) - eina_log_print(EINA_LOG_DOMAIN_GLOBAL, - EINA_LOG_LEVEL_CRITICAL, file, fnc, line, - "*** Eina Magic Check Failed !!!\n" - " Input handle has already been freed!\n" - "*** NAUGHTY PROGRAMMER!!!\n" - "*** SPANK SPANK SPANK!!!\n" - "*** Now go fix your code. Tut tut tut!\n" - "\n"); - else if (m != req_m) - eina_log_print(EINA_LOG_DOMAIN_GLOBAL, - EINA_LOG_LEVEL_CRITICAL, file, fnc, line, - "*** Eina Magic Check Failed !!!\n" - " Input handle is wrong type\n" - " Expected: %08x - %s\n" - " Supplied: %08x - %s\n" - "*** NAUGHTY PROGRAMMER!!!\n" - "*** SPANK SPANK SPANK!!!\n" - "*** Now go fix your code. Tut tut tut!\n" - "\n", req_m, eina_magic_string_get(req_m), - m, eina_magic_string_get(m)); - else - eina_log_print(EINA_LOG_DOMAIN_GLOBAL, - EINA_LOG_LEVEL_CRITICAL, file, fnc, line, - "*** Eina Magic Check Failed !!!\n" - " Why did you call me !\n" - "*** NAUGHTY PROGRAMMER!!!\n" - "*** SPANK SPANK SPANK!!!\n" - "*** Now go fix your code. Tut tut tut!\n" - "\n"); -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_main.c b/tests/suite/ecore/src/lib/eina_main.c deleted file mode 100644 index 46f1ddfdf3..0000000000 --- a/tests/suite/ecore/src/lib/eina_main.c +++ /dev/null @@ -1,369 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> - -#ifdef EFL_HAVE_POSIX_THREADS -#include <pthread.h> -#endif - -#ifdef EFL_HAVE_WIN32_THREADS -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_types.h" -#include "eina_main.h" -#include "eina_error.h" -#include "eina_log.h" -#include "eina_hash.h" -#include "eina_binshare.h" -#include "eina_stringshare.h" -#include "eina_ustringshare.h" -#include "eina_list.h" -#include "eina_matrixsparse.h" -#include "eina_array.h" -#include "eina_counter.h" -#include "eina_benchmark.h" -#include "eina_magic.h" -#include "eina_rectangle.h" -#include "eina_safety_checks.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV }; - -static int _eina_main_count = 0; -#ifdef EFL_HAVE_THREADS -static int _eina_main_thread_count = 0; -#endif -static int _eina_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__) - -#ifdef EFL_HAVE_THREADS -static Eina_Bool _threads_activated = EINA_FALSE; -#ifdef EFL_HAVE_POSIX_THREADS -static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; -#define LOCK() if(_threads_activated) pthread_mutex_lock(&_mutex) -#define UNLOCK() if(_threads_activated) pthread_mutex_unlock(&_mutex) -#define UNLOCK_FORCE() pthread_mutex_unlock(&_mutex) -#else /* EFL_HAVE_WIN32_THREADS */ -static HANDLE _mutex = NULL; -#define LOCK() if(_threads_activated) WaitForSingleObject(_mutex, INFINITE) -#define UNLOCK() if(_threads_activated) ReleaseMutex(_mutex) -#define UNLOCK_FORCE() ReleaseMutex(_mutex) -#endif -#else -#define LOCK() do {} while (0) -#define UNLOCK() do {} while (0) -#define UNLOCK_FORCE() do {} while (0) -#endif - -/* place module init/shutdown functions here to avoid other modules - * calling them by mistake. - */ -#define S(x) extern Eina_Bool eina_ ## x ## _init(void); \ - extern Eina_Bool eina_ ## x ## _shutdown(void) -S(log); -S(error); -S(safety_checks); -S(magic_string); -S(iterator); -S(accessor); -S(array); -S(module); -S(mempool); -S(list); -S(binshare); -S(stringshare); -S(ustringshare); -S(matrixsparse); -S(convert); -S(counter); -S(benchmark); -S(rectangle); -S(strbuf); -S(ustrbuf); -S(quadtree); -#undef S - -struct eina_desc_setup { - const char *name; - Eina_Bool(*init) (void); - Eina_Bool(*shutdown) (void); -}; - -static const struct eina_desc_setup _eina_desc_setup[] = { -#define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown} - /* log is a special case as it needs printf */ - S(error), - S(safety_checks), - S(magic_string), - S(iterator), - S(accessor), - S(array), - S(module), - S(mempool), - S(list), - S(binshare), - S(stringshare), - S(ustringshare), - S(matrixsparse), - S(convert), - S(counter), - S(benchmark), - S(rectangle), - S(strbuf), - S(ustrbuf), - S(quadtree) -#undef S -}; - -static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / - sizeof(_eina_desc_setup[0]); - -static void _eina_shutdown_from_desc(const struct eina_desc_setup *itr) -{ - for (itr--; itr >= _eina_desc_setup; itr--) { - if (!itr->shutdown()) - ERR("Problems shutting down eina module '%s', ignored.", itr->name); - } - - eina_log_domain_unregister(_eina_log_dom); - _eina_log_dom = -1; - eina_log_shutdown(); -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Main_Group Main - * - * @brief These functions provide general initialisation and shut down - * functions. - * - * @{ - */ - -/** - * @var eina_version - * @brief Eina version (defined at configuration time) - */ -EAPI Eina_Version *eina_version = &_version; - -/** - * @brief Initialize the Eina library. - * - * @return 1 or greater on success, 0 on error. - * - * This function sets up all the eina modules. It returns 0 on - * failure (that is, when one of the module fails to initialize), - * otherwise it returns the number of times it has already been - * called. - * - * When Eina is not used anymore, call eina_shutdown() to shut down - * the Eina library. - */ -EAPI int eina_init(void) -{ - const struct eina_desc_setup *itr, *itr_end; - - if (EINA_LIKELY(_eina_main_count > 0)) - return ++_eina_main_count; - - if (!eina_log_init()) { - fprintf(stderr, - "Could not initialize eina logging system.\n"); - return 0; - } - - _eina_log_dom = - eina_log_domain_register("eina", EINA_LOG_COLOR_DEFAULT); - if (_eina_log_dom < 0) { - EINA_LOG_ERR("Could not register log domain: eina"); - eina_log_shutdown(); - return 0; - } - - itr = _eina_desc_setup; - itr_end = itr + _eina_desc_setup_len; - for (; itr < itr_end; itr++) { - if (!itr->init()) { - ERR("Could not initialize eina module '%s'.", - itr->name); - _eina_shutdown_from_desc(itr); - return 0; - } - } - - _eina_main_count = 1; - return 1; -} - -/** - * @brief Shut down the Eina library. - * - * @return 0 when all the modules is completely shut down, 1 or - * greater otherwise. - * - * This function shuts down the Eina library. It returns 0 when it has - * been called the same number of times than eina_init(). In that case - * it shut down all the Eina modules. - * - * Once this function succeeds (that is, @c 0 is returned), you must - * not call any of the Eina function anymore. You must call - * eina_init() again to use the Eina functions again. - */ -EAPI int eina_shutdown(void) -{ - _eina_main_count--; - if (EINA_UNLIKELY(_eina_main_count == 0)) - _eina_shutdown_from_desc(_eina_desc_setup + - _eina_desc_setup_len); - - return _eina_main_count; -} - - -/** - * @brief Initialize the mutexes of the Eina library. - * - * @return 1 or greater on success, 0 on error. - * - * This function sets up all the mutexes in all eina modules. It returns 0 on - * failure (that is, when one of the module fails to initialize), - * otherwise it returns the number of times it has already been - * called. - * - * When the mutexes are not used anymore, call eina_threads_shutdown() to shut down - * the mutexes. - */ -EAPI int eina_threads_init(void) -{ -#ifdef EFL_HAVE_THREADS - int ret; - -#ifdef EFL_HAVE_WIN32_THREADS - if (!_mutex) - _mutex = CreateMutex(NULL, FALSE, NULL); - - if (!_mutex) - return 0; - -#endif - - LOCK(); - ++_eina_main_thread_count; - ret = _eina_main_thread_count; - - if (_eina_main_thread_count > 1) { - UNLOCK(); - return ret; - } - - eina_share_common_threads_init(); - eina_log_threads_init(); - _threads_activated = EINA_TRUE; - - return ret; -#else - return 0; -#endif -} - -/** - * @brief Shut down mutexes in the Eina library. - * - * @return 0 when all mutexes are completely shut down, 1 or - * greater otherwise. - * - * This function shuts down the mutexes in the Eina library. It returns 0 when it has - * been called the same number of times than eina_threads_init(). In that case - * it shut down all the mutexes. - * - * Once this function succeeds (that is, @c 0 is returned), you must - * not call any of the Eina function in a thread anymore. You must call - * eina_threads_init() again to use the Eina functions in a thread again. - */ -EAPI int eina_threads_shutdown(void) -{ -#ifdef EFL_HAVE_THREADS - int ret; - - LOCK(); - ret = --_eina_main_thread_count; - if (_eina_main_thread_count > 0) { - UNLOCK(); - return ret; - } - - eina_share_common_threads_shutdown(); - eina_log_threads_shutdown(); - - _threads_activated = EINA_FALSE; - - UNLOCK_FORCE(); - -#ifdef EFL_HAVE_WIN32_THREADS - if (_mutex) - CloseHandle(_mutex); - -#endif - - return ret; -#else - return 0; -#endif -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_matrixsparse.c b/tests/suite/ecore/src/lib/eina_matrixsparse.c deleted file mode 100644 index cb17d885f1..0000000000 --- a/tests/suite/ecore/src/lib/eina_matrixsparse.c +++ /dev/null @@ -1,1615 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2009 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 <https://www.gnu.org/licenses/>. - */ - - -/** - * @page tutorial_matrixsparse_page Sparse Matrix Tutorial - * - * to be written... - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_error.h" -#include "eina_log.h" -#include "eina_magic.h" -#include "eina_mempool.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_matrixsparse.h" - - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static const char EINA_MAGIC_MATRIXSPARSE_STR[] = "Eina Matrixsparse"; -static const char EINA_MAGIC_MATRIXSPARSE_ROW_STR[] = - "Eina Matrixsparse Row"; -static const char EINA_MAGIC_MATRIXSPARSE_CELL_STR[] = - "Eina Matrixsparse Cell"; -static const char EINA_MAGIC_MATRIXSPARSE_ITERATOR_STR[] = - "Eina Matrixsparse Iterator"; -static const char EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR_STR[] = - "Eina Matrixsparse Row Accessor"; -static const char EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR_STR[] = - "Eina Matrixsparse Row Iterator"; -static const char EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR_STR[] = - "Eina Matrixsparse Cell Accessor"; -static const char EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR_STR[] = - "Eina Matrixsparse Cell Iterator"; - - -#define EINA_MAGIC_CHECK_MATRIXSPARSE(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE); \ - return __VA_ARGS__; \ - } \ - } while(0) - -#define EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_ROW)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_ROW); \ - return __VA_ARGS__; \ - } \ - } while(0) - -#define EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_CELL)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_CELL); \ - return __VA_ARGS__; \ - } \ - } while(0) - -#define EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_ITERATOR)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_ITERATOR); \ - return __VA_ARGS__; \ - } \ - } while(0) - -struct _Eina_Matrixsparse_Cell { - Eina_Matrixsparse_Cell *next; - Eina_Matrixsparse_Cell *prev; - - void *data; - unsigned long col; - - Eina_Matrixsparse_Row *parent; - - EINA_MAGIC}; - -struct _Eina_Matrixsparse_Row { - Eina_Matrixsparse_Row *next; - Eina_Matrixsparse_Row *prev; - - Eina_Matrixsparse_Cell *cols; - Eina_Matrixsparse_Cell *last_col; - Eina_Matrixsparse_Cell *last_used; /* fast sequential access */ - unsigned long row; - - Eina_Matrixsparse *parent; - - EINA_MAGIC}; - -struct _Eina_Matrixsparse { - Eina_Matrixsparse_Row *rows; - Eina_Matrixsparse_Row *last_row; - Eina_Matrixsparse_Row *last_used; /* fast sequential access */ - - struct { - unsigned long rows; - unsigned long cols; - } size; - - struct { - void (*func) (void *user_data, void *cell_data); - void *user_data; - } free; - - EINA_MAGIC}; - -typedef struct _Eina_Matrixsparse_Iterator Eina_Matrixsparse_Iterator; -typedef struct _Eina_Matrixsparse_Iterator_Complete - Eina_Matrixsparse_Iterator_Complete; - -struct _Eina_Matrixsparse_Iterator { - Eina_Iterator iterator; - - const Eina_Matrixsparse *m; - struct { - const Eina_Matrixsparse_Row *row; - const Eina_Matrixsparse_Cell *col; - } ref; - - EINA_MAGIC}; - -struct _Eina_Matrixsparse_Iterator_Complete { - Eina_Iterator iterator; - - const Eina_Matrixsparse *m; - struct { - const Eina_Matrixsparse_Row *row; - const Eina_Matrixsparse_Cell *col; - } ref; - - struct { - unsigned long row, col; - } idx; - - struct { - Eina_Matrixsparse_Row row; - Eina_Matrixsparse_Cell col; - } dummy; - - EINA_MAGIC}; - -/** - * @todo Eina_Matrixsparse_Row_Iterator: iterator over rows in matrix - * @todo Eina_Matrixsparse_Row_Accessor: accessor over rows in matrix - * @todo Eina_Matrixsparse_Cell_Iterator: iterator over cells in row - * @todo Eina_Matrixsparse_Cell_Accessor: accessor over cells in row - */ - -static int _eina_matrixsparse_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_matrixsparse_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_matrixsparse_log_dom, __VA_ARGS__) - -static Eina_Mempool *_eina_matrixsparse_cell_mp = NULL; -static Eina_Mempool *_eina_matrixsparse_row_mp = NULL; - -static inline void -_eina_matrixsparse_cell_free(Eina_Matrixsparse_Cell * c, - void (*free_func) (void *, void *), - void *user_data) -{ - if (free_func) - free_func(user_data, c->data); - - EINA_MAGIC_SET(c, EINA_MAGIC_NONE); - eina_mempool_free(_eina_matrixsparse_cell_mp, c); -} - -static inline void -_eina_matrixsparse_cell_unlink(Eina_Matrixsparse_Cell * c) -{ - Eina_Matrixsparse_Row *r = c->parent; - - if (r->last_used == c) { - if (c->next) - r->last_used = c->next; - else - r->last_used = c->prev; - } - - if (r->last_col == c) - r->last_col = c->prev; - - if (r->cols == c) - r->cols = c->next; - - if (c->next && c->prev) { - c->next->prev = c->prev; - c->prev->next = c->next; - } else if (c->next) - c->next->prev = NULL; - else if (c->prev) - c->prev->next = NULL; -} - -static inline void -_eina_matrixsparse_row_cells_free(Eina_Matrixsparse_Row * r, - void (*free_func) (void *, void *), - void *user_data) -{ - Eina_Matrixsparse_Cell *c = r->cols; - while (c) { - Eina_Matrixsparse_Cell *c_aux = c; - c = c->next; - _eina_matrixsparse_cell_free(c_aux, free_func, user_data); - } -} - -static inline void -_eina_matrixsparse_row_free(Eina_Matrixsparse_Row * r, - void (*free_func) (void *, void *), - void *user_data) -{ - _eina_matrixsparse_row_cells_free(r, free_func, user_data); - EINA_MAGIC_SET(r, EINA_MAGIC_NONE); - eina_mempool_free(_eina_matrixsparse_row_mp, r); -} - -static inline void _eina_matrixsparse_row_unlink(Eina_Matrixsparse_Row * r) -{ - Eina_Matrixsparse *m = r->parent; - - if (m->last_used == r) { - if (r->next) - m->last_used = r->next; - else - m->last_used = r->prev; - } - - if (m->last_row == r) - m->last_row = r->prev; - - if (m->rows == r) - m->rows = r->next; - - if (r->next && r->prev) { - r->next->prev = r->prev; - r->prev->next = r->next; - } else if (r->next) - r->next->prev = NULL; - else if (r->prev) - r->prev->next = NULL; -} - -static inline void -_eina_matrixsparse_row_find_parms_get(const Eina_Matrixsparse * m, - unsigned long row, - Eina_Matrixsparse_Row ** p_r, - int *p_dir) -{ - Eina_Matrixsparse_Row *r; - unsigned long dist; - int dir; - - dist = row - m->rows->row; - r = m->rows; - dir = 1; - if (dist > m->last_row->row - row) { - dist = m->last_row->row - row; - r = m->last_row; - dir = -1; - } - - if (m->last_used) { - if (m->last_used->row < row) { - if (dist > row - m->last_used->row) { -/* dist = row = m->last_used->row; */ - r = m->last_used; - dir = 1; - } - } else if (dist > m->last_used->row - row) { -/* dist = m->last_used->row - row; */ - r = m->last_used; - dir = -1; - } - } - - *p_r = r; - *p_dir = dir; -} - -static inline void -_eina_matrixsparse_row_cell_find_parms_get(const Eina_Matrixsparse_Row * r, - unsigned long col, - Eina_Matrixsparse_Cell ** p_c, - int *p_dir) -{ - Eina_Matrixsparse_Cell *c; - unsigned long dist; - int dir; - - dist = col - r->cols->col; - c = r->cols; - dir = 1; - if (dist > r->last_col->col - col) { - dist = r->last_col->col - col; - c = r->last_col; - dir = -1; - } - - if (r->last_used) { - if (r->last_used->col < col) { - if (dist > col - r->last_used->col) { -/* dist = col = r->last_used->col; */ - c = r->last_used; - dir = 1; - } - } else if (dist > r->last_used->col - col) { -/* dist = r->last_used->col - col; */ - c = r->last_used; - dir = -1; - } - } - - *p_c = c; - *p_dir = dir; -} - -static inline Eina_Matrixsparse_Row *_eina_matrixsparse_row_idx_get(const - Eina_Matrixsparse - * m, - unsigned - long - row) -{ - Eina_Matrixsparse_Row *r; - int dir; - - if (!m->rows) - return NULL; - - if (m->rows->row == row) - return m->rows; - else if (m->rows->row > row) - return NULL; - - if (m->last_row->row == row) - return m->last_row; - else if (m->last_row->row < row) - return NULL; - - if ((m->last_used) && (m->last_used->row == row)) - return m->last_used; - - _eina_matrixsparse_row_find_parms_get(m, row, &r, &dir); - assert(dir != 0); - if (dir > 0) { - for (; r; r = r->next) - if (r->row == row) { - ((Eina_Matrixsparse *) m)->last_used = r; - return r; - } else if (r->row > row) - return NULL; - - } else if (dir < 0) { - for (; r; r = r->prev) - if (r->row == row) { - ((Eina_Matrixsparse *) m)->last_used = r; - return r; - } else if (r->row < row) - return NULL; - } - - return NULL; -} - -static inline Eina_Matrixsparse_Cell - *_eina_matrixsparse_row_cell_idx_get(const Eina_Matrixsparse_Row * r, - unsigned long col) -{ - Eina_Matrixsparse_Cell *c; - int dir; - - if (!r->cols) - return NULL; - - if (r->cols->col == col) - return r->cols; - else if (r->cols->col > col) - return NULL; - - if (r->last_col->col == col) - return r->last_col; - else if (r->last_col->col < col) - return NULL; - - if ((r->last_used) && (r->last_used->col == col)) - return r->last_used; - - _eina_matrixsparse_row_cell_find_parms_get(r, col, &c, &dir); - assert(dir != 0); - if (dir > 0) { - for (; r; c = c->next) - if (c->col == col) { - ((Eina_Matrixsparse_Row *) r)->last_used = - c; - return c; - } else if (c->col > col) - return NULL; - - } else if (dir < 0) { - for (; r; c = c->prev) - if (c->col == col) { - ((Eina_Matrixsparse_Row *) r)->last_used = - c; - return c; - } else if (c->col < col) - return NULL; - } - - return NULL; -} - -static inline Eina_Matrixsparse_Cell *_eina_matrixsparse_cell_idx_get(const - Eina_Matrixsparse - * m, - unsigned - long - row, - unsigned - long - col) -{ - Eina_Matrixsparse_Row *r = _eina_matrixsparse_row_idx_get(m, row); - if (!r) - return NULL; - - return _eina_matrixsparse_row_cell_idx_get(r, col); -} - -static inline void -_eina_matrixsparse_row_idx_siblings_find(const Eina_Matrixsparse * m, - unsigned long row, - Eina_Matrixsparse_Row ** p_prev, - Eina_Matrixsparse_Row ** p_next) -{ - Eina_Matrixsparse_Row *r; - int dir; - - _eina_matrixsparse_row_find_parms_get(m, row, &r, &dir); - assert(dir != 0); - if (dir > 0) { - for (; r; r = r->next) - if (r->row > row) - break; - - assert(r != NULL); - *p_prev = r->prev; - *p_next = r; - } else if (dir < 0) { - for (; r; r = r->prev) - if (r->row < row) - break; - - assert(r != NULL); - *p_prev = r; - *p_next = r->next; - } -} - -static inline void -_eina_matrixsparse_row_cell_idx_siblings_find(const Eina_Matrixsparse_Row * - r, unsigned long col, - Eina_Matrixsparse_Cell ** - p_prev, - Eina_Matrixsparse_Cell ** - p_next) -{ - Eina_Matrixsparse_Cell *c; - int dir; - - _eina_matrixsparse_row_cell_find_parms_get(r, col, &c, &dir); - assert(dir != 0); - if (dir > 0) { - for (; c; c = c->next) - if (c->col > col) - break; - - assert(c != NULL); - *p_prev = c->prev; - *p_next = c; - } else if (dir < 0) { - for (; c; c = c->prev) - if (c->col < col) - break; - - assert(c != NULL); - *p_prev = c; - *p_next = c->next; - } -} - -static inline Eina_Matrixsparse_Row - *_eina_matrixsparse_row_idx_add(Eina_Matrixsparse * m, - unsigned long row) -{ - Eina_Matrixsparse_Row *r = eina_mempool_malloc - (_eina_matrixsparse_row_mp, sizeof(Eina_Matrixsparse_Row)); - if (!r) - return NULL; - - if (!m->rows) { - r->prev = NULL; - r->next = NULL; - m->rows = r; - m->last_row = r; - } else if (row < m->rows->row) { - r->prev = NULL; - r->next = m->rows; - m->rows->prev = r; - m->rows = r; - } else if (row > m->last_row->row) { - r->prev = m->last_row; - m->last_row->next = r; - r->next = NULL; - m->last_row = r; - } else { - Eina_Matrixsparse_Row *prev = NULL, *next = NULL; - _eina_matrixsparse_row_idx_siblings_find(m, row, &prev, - &next); - assert(prev != NULL); - assert(next != NULL); - r->prev = prev; - r->next = next; - prev->next = r; - next->prev = r; - } - - r->cols = NULL; - r->last_col = NULL; - r->last_used = NULL; - r->row = row; - r->parent = m; - EINA_MAGIC_SET(r, EINA_MAGIC_MATRIXSPARSE_ROW); - m->last_used = r; - return r; -} - -static inline Eina_Matrixsparse_Cell - *_eina_matrixsparse_row_cell_idx_add(Eina_Matrixsparse_Row * r, - unsigned long col, - const void *data) -{ - Eina_Matrixsparse_Cell *c = eina_mempool_malloc - (_eina_matrixsparse_cell_mp, sizeof(Eina_Matrixsparse_Cell)); - if (!c) - return NULL; - - if (!r->cols) { - c->prev = NULL; - c->next = NULL; - r->cols = c; - r->last_col = c; - } else if (col < r->cols->col) { - c->prev = NULL; - c->next = r->cols; - r->cols->prev = c; - r->cols = c; - } else if (col > r->last_col->col) { - c->prev = r->last_col; - r->last_col->next = c; - c->next = NULL; - r->last_col = c; - } else { - Eina_Matrixsparse_Cell *prev = NULL, *next = NULL; - _eina_matrixsparse_row_cell_idx_siblings_find(r, col, - &prev, - &next); - assert(prev != NULL); - assert(next != NULL); - c->prev = prev; - c->next = next; - prev->next = c; - next->prev = c; - } - - c->data = (void *) data; - c->col = col; - c->parent = r; - EINA_MAGIC_SET(c, EINA_MAGIC_MATRIXSPARSE_CELL); - r->last_used = c; - return c; -} - -static inline Eina_Bool -_eina_matrixsparse_cell_idx_add(Eina_Matrixsparse * m, - unsigned long row, - unsigned long col, const void *data) -{ - Eina_Matrixsparse_Row *r = _eina_matrixsparse_row_idx_get(m, row); - if (!r) - r = _eina_matrixsparse_row_idx_add(m, row); - - if (!r) - return 0; - - if (_eina_matrixsparse_row_cell_idx_add(r, col, data)) - return 1; - - if (r->cols) - return 0; - - _eina_matrixsparse_row_unlink(r); - _eina_matrixsparse_row_free(r, m->free.func, m->free.user_data); - return 0; -} - -/*============================================================================* -* Iterators * -*============================================================================*/ -static Eina_Bool -_eina_matrixsparse_iterator_next(Eina_Matrixsparse_Iterator * it, - void **data) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, EINA_FALSE); - - /* do not touch it->idx */ - - if (!it->ref.col) - return 0; - - *data = (Eina_Matrixsparse_Cell *) it->ref.col; - - it->ref.col = it->ref.col->next; - if (!it->ref.col) { - it->ref.row = it->ref.row->next; - if (it->ref.row) - it->ref.col = it->ref.row->cols; - } - - return 1; -} - -static Eina_Matrixsparse - *_eina_matrixsparse_iterator_get_container(Eina_Matrixsparse_Iterator * - it) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, NULL); - return (Eina_Matrixsparse *) it->m; -} - -static void -_eina_matrixsparse_iterator_free(Eina_Matrixsparse_Iterator * it) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it); - EINA_MAGIC_SET(it, EINA_MAGIC_NONE); - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE); - free(it); -} - -static Eina_Bool -_eina_matrixsparse_iterator_complete_next -(Eina_Matrixsparse_Iterator_Complete * it, void **data) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, EINA_FALSE); - - if (it->idx.row >= it->m->size.rows) - return 0; - - if (it->dummy.col.data) - ERR("Last iterator call changed dummy cell!"); - - if ((it->ref.col) && - (it->ref.col->col == it->idx.col) && - (it->ref.row->row == it->idx.row)) { - *data = (Eina_Matrixsparse_Cell *) it->ref.col; - it->ref.col = it->ref.col->next; - if (!it->ref.col) { - it->ref.row = it->ref.row->next; - if (it->ref.row) - it->ref.col = it->ref.row->cols; - } - } else { - it->dummy.col.data = NULL; - it->dummy.col.col = it->idx.col; - it->dummy.row.row = it->idx.row; - *data = &it->dummy.col; - } - - it->idx.col++; - if (it->idx.col == it->m->size.cols) { - it->idx.col = 0; - it->idx.row++; - } - - return 1; -} - -static Eina_Matrixsparse - *_eina_matrixsparse_iterator_complete_get_container - (Eina_Matrixsparse_Iterator_Complete * it) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, NULL); - return (Eina_Matrixsparse *) it->m; -} - -static void -_eina_matrixsparse_iterator_complete_free -(Eina_Matrixsparse_Iterator_Complete * it) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it); - - if (it->dummy.col.data) - ERR("Last iterator call changed dummy cell!"); - - EINA_MAGIC_SET(it, EINA_MAGIC_NONE); - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE); - free(it); -} - - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the matrixsparse module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the matrixsparse module of Eina. It is called by - * eina_init(). - * - * This function creates mempool to speed up matrix rows and cells - * management, using EINA_MEMPOOL environment variable if it is set to - * choose the memory pool type to use. - * - * @see eina_init() - */ -Eina_Bool eina_matrixsparse_init(void) -{ - const char *choice, *tmp; - - _eina_matrixsparse_log_dom = - eina_log_domain_register("eina_matrixsparse", - EINA_LOG_COLOR_DEFAULT); - if (_eina_matrixsparse_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_matrixsparse"); - return EINA_FALSE; - } -#ifdef EINA_DEFAULT_MEMPOOL - choice = "pass_through"; -#else - choice = "chained_mempool"; -#endif - tmp = getenv("EINA_MEMPOOL"); - if (tmp && tmp[0]) - choice = tmp; - - _eina_matrixsparse_cell_mp = eina_mempool_add - (choice, - "matrixsparse_cell", - NULL, sizeof(Eina_Matrixsparse_Cell), 120); - if (!_eina_matrixsparse_cell_mp) { - ERR("Mempool for matrixsparse_cell cannot be allocated in matrixsparse init."); - goto on_init_fail; - } - - _eina_matrixsparse_row_mp = eina_mempool_add - (choice, "matrixsparse_row", NULL, - sizeof(Eina_Matrixsparse_Row), 120); - if (!_eina_matrixsparse_row_mp) { - ERR("Mempool for matrixsparse_row cannot be allocated in matrixsparse init."); - goto on_init_fail; - } -#define EMS(n) eina_magic_string_static_set(n, n ## _STR) - EMS(EINA_MAGIC_MATRIXSPARSE); - EMS(EINA_MAGIC_MATRIXSPARSE_ROW); - EMS(EINA_MAGIC_MATRIXSPARSE_CELL); - EMS(EINA_MAGIC_MATRIXSPARSE_ITERATOR); - EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR); - EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR); - EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR); - EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR); -#undef EMS - - return EINA_TRUE; - - on_init_fail: - eina_log_domain_unregister(_eina_matrixsparse_log_dom); - _eina_matrixsparse_log_dom = -1; - return EINA_FALSE; -} - -/** - * @internal - * @brief Shut down the matrixsparse module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the matrixsparse module set up by - * eina_matrixsparse_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_matrixsparse_shutdown(void) -{ - eina_mempool_del(_eina_matrixsparse_row_mp); - eina_mempool_del(_eina_matrixsparse_cell_mp); - - eina_log_domain_unregister(_eina_matrixsparse_log_dom); - _eina_matrixsparse_log_dom = -1; - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Matrixsparse_Group Sparse Matrix - * - * @brief These functions provide matrix sparse management. - * - * For more information, you can look at the @ref tutorial_matrixsparse_page. - * - * @{ - */ - -/** - * @brief Create a new Sparse Matrix. - * - * @param rows number of rows in matrix. Operations with rows greater than this - * value will fail. - * @param cols number of columns in matrix. Operations with columns greater - * than this value will fail. - * @param free_func used to delete cell data contents, used by - * eina_matrixsparse_free(), eina_matrixsparse_size_set(), - * eina_matrixsparse_row_idx_clear(), - * eina_matrixsparse_column_idx_clear(), - * eina_matrixsparse_cell_idx_clear() and possible others. - * @param user_data given to @a free_func as first parameter. - * - * @return newly allocated matrix or NULL if allocation failed and eina_error - * is set. - */ -EAPI Eina_Matrixsparse *eina_matrixsparse_new(unsigned long rows, - unsigned long cols, - void (*free_func) (void - *user_data, - void - *cell_data), - const void *user_data) -{ - Eina_Matrixsparse *m; - - EINA_SAFETY_ON_FALSE_RETURN_VAL(rows > 0, NULL); - EINA_SAFETY_ON_FALSE_RETURN_VAL(cols > 0, NULL); - - m = malloc(sizeof(Eina_Matrixsparse)); - if (!m) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(m, EINA_MAGIC_MATRIXSPARSE); - - m->rows = NULL; - m->last_row = NULL; - m->last_used = NULL; - - m->size.rows = rows; - m->size.cols = cols; - m->free.func = free_func; - m->free.user_data = (void *) user_data; - - eina_error_set(0); - return m; -} - -/** - * @brief Free resources allocated to Sparse Matrix. - * - * @param m The Sparse Matrix instance to free, must @b not be @c NULL. - */ -EAPI void eina_matrixsparse_free(Eina_Matrixsparse * m) -{ - void (*free_func) (void *, void *); - void *user_data; - - Eina_Matrixsparse_Row *r; - EINA_MAGIC_CHECK_MATRIXSPARSE(m); - - free_func = m->free.func; - user_data = m->free.user_data; - - r = m->rows; - while (r) { - Eina_Matrixsparse_Row *r_aux = r; - r = r->next; - _eina_matrixsparse_row_free(r_aux, free_func, user_data); - } - - EINA_MAGIC_SET(m, EINA_MAGIC_NONE); - free(m); -} - -/** - * @brief Get the current size of Sparse Matrix. - * - * The given parameters are guaranteed to be set if they're not NULL, - * even if this function fails (ie: @a m is not a valid matrix instance). - * - * @param m the sparse matrix to operate on. - * @param rows returns the number of rows, may be NULL. If @a m is invalid, - * returned value is zero, otherwise it's a positive integer. - * @param cols returns the number of columns, may be NULL. If @a m is - * invalid, returned value is zero, otherwise it's a positive integer. - */ -EAPI void -eina_matrixsparse_size_get(const Eina_Matrixsparse * m, - unsigned long *rows, unsigned long *cols) -{ - if (rows) - *rows = 0; - - if (cols) - *cols = 0; - - EINA_MAGIC_CHECK_MATRIXSPARSE(m); - if (rows) - *rows = m->size.rows; - - if (cols) - *cols = m->size.cols; -} - -/** - * @brief Resize the Sparse Matrix. - * - * This will resize the sparse matrix, possibly freeing cells on rows - * and columns that will cease to exist. - * - * @param m the sparse matrix to operate on. - * @param rows the new number of rows, must be greater than zero. - * @param cols the new number of columns, must be greater than zero. - * @return 1 on success, 0 on failure. - * - * @warning cells, rows or columns are not reference counted and thus - * after this call any reference might be invalid if instance were - * freed. - */ -EAPI Eina_Bool -eina_matrixsparse_size_set(Eina_Matrixsparse * m, - unsigned long rows, unsigned long cols) -{ - Eina_Bool update_last_used_row; - Eina_Matrixsparse_Row *r; - void (*free_func) (void *, void *); - void *user_data; - - EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(rows > 0, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(cols > 0, 0); - - if ((rows == m->size.rows) && (cols == m->size.cols)) - return 1; - - update_last_used_row = ((m->last_used) - && (m->last_used->row >= rows)); - free_func = m->free.func; - user_data = m->free.user_data; - - r = m->last_row; - while (r && r->row >= rows) { - Eina_Matrixsparse_Row *r_aux = r; - r = r->prev; - _eina_matrixsparse_row_free(r_aux, free_func, user_data); - } - if (!r) { - m->last_row = NULL; - m->rows = NULL; - } else if (r != m->last_row) { - r->next = NULL; - m->last_row = r; - } - - if (update_last_used_row) - m->last_used = m->last_row; - - r = m->rows; - while (r) { - Eina_Matrixsparse_Cell *c = r->last_col; - Eina_Bool update_last_used_col; - update_last_used_col = ((r->last_used) - && (r->last_used->col >= cols)); - while (c && c->col >= cols) { - Eina_Matrixsparse_Cell *c_aux = c; - c = c->prev; - _eina_matrixsparse_cell_free(c_aux, free_func, - user_data); - } - if (!c) { - Eina_Matrixsparse_Row *r_aux = r; - r->cols = NULL; - r->last_col = NULL; - if (r->next) - r->next->prev = r->prev; - else - m->last_row = r->prev; - - if (r->prev) - r->prev->next = r->next; - else - m->rows = r->next; - - r = r->next; - _eina_matrixsparse_row_free(r_aux, free_func, - user_data); - } else { - if (c != r->last_col) { - c->next = NULL; - r->last_col = c; - } - - if (update_last_used_col) - r->last_used = r->last_col; - - r = r->next; - } - } - - update_last_used_row = 0; - if (m->last_used) { - if (m->last_row) - update_last_used_row = - m->last_used->row > m->last_row->row; - else - update_last_used_row = 1; - } - - if (update_last_used_row) - m->last_used = m->last_row; - - m->size.rows = rows; - m->size.cols = cols; - return 1; -} - -/** - * Get the cell reference inside Sparse Matrix. - * - * @param m the sparse matrix to operate on. - * @param row the new number of row to clear. - * @param col the new number of column to clear. - * @param cell pointer to return cell reference, if any exists. - * - * @return 1 on success, 0 on failure. It is considered success if did not - * exist but index is inside matrix size, in this case @c *cell == NULL - * - * @see eina_matrixsparse_cell_data_get() - * @see eina_matrixsparse_data_idx_get() - */ -EAPI Eina_Bool -eina_matrixsparse_cell_idx_get(const Eina_Matrixsparse * m, - unsigned long row, - unsigned long col, - Eina_Matrixsparse_Cell ** cell) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); - EINA_SAFETY_ON_NULL_RETURN_VAL(cell, 0); - *cell = NULL; - EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); - *cell = _eina_matrixsparse_cell_idx_get(m, row, col); - return 1; -} - -/** - * Get data associated with given cell reference. - * - * @param cell given cell reference, must @b not be @c NULL. - * - * @return data associated with given cell. - * - * @see eina_matrixsparse_cell_idx_get() - * @see eina_matrixsparse_data_idx_get() - */ -EAPI void *eina_matrixsparse_cell_data_get(const Eina_Matrixsparse_Cell * - cell) -{ - EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, NULL); - return cell->data; -} - -/** - * Get data associated with given cell given its indexes. - * - * @param m the sparse matrix to operate on. - * @param row the new number of row to clear. - * @param col the new number of column to clear. - * - * @return data associated with given cell or NULL if nothing is associated. - * - * @see eina_matrixsparse_cell_idx_get() - * @see eina_matrixsparse_cell_data_get() - */ -EAPI void *eina_matrixsparse_data_idx_get(const Eina_Matrixsparse * m, - unsigned long row, - unsigned long col) -{ - Eina_Matrixsparse_Cell *c; - EINA_MAGIC_CHECK_MATRIXSPARSE(m, NULL); - c = _eina_matrixsparse_cell_idx_get(m, row, col); - if (c) - return c->data; - else - return NULL; -} - -/** - * Get position (indexes) of the given cell. - * - * @param cell the cell reference, must @b not be @c NULL. - * @param row where to store cell row number, may be @c NULL. - * @param col where to store cell column number, may be @c NULL. - * - * @return 1 on success, 0 otherwise (@c cell is @c NULL). - */ -EAPI Eina_Bool -eina_matrixsparse_cell_position_get(const Eina_Matrixsparse_Cell * cell, - unsigned long *row, unsigned long *col) -{ - if (row) - *row = 0; - - if (col) - *col = 0; - - EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); - EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0); - if (row) - *row = cell->parent->row; - - if (col) - *col = cell->col; - - return 1; -} - -/** - * Change cell reference value without freeing the possibly existing old value. - * - * @param cell the cell reference, must @b not be @c NULL. - * @param data new data to set. - * @param p_old returns the old value intact (not freed). - * - * @return 1 on success, 0 otherwise (@a cell is @c NULL). - * - * @see eina_matrixsparse_cell_data_set() - * @see eina_matrixsparse_data_idx_replace() - */ -EAPI Eina_Bool -eina_matrixsparse_cell_data_replace(Eina_Matrixsparse_Cell * cell, - const void *data, void **p_old) -{ - if (p_old) - *p_old = NULL; - - EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); - - if (p_old) - *p_old = cell->data; - - cell->data = (void *) data; - return 1; -} - -/** - * Change cell value freeing the possibly existing old value. - * - * In contrast to eina_matrixsparse_cell_data_replace(), this function will - * call @c free_func() on existing value. - * - * @param cell the cell reference, must @b not be @c NULL. - * @param data new data to set. - * - * @return 1 on success, 0 otherwise (@a cell is @c NULL). - * - * @see eina_matrixsparse_cell_data_replace() - * @see eina_matrixsparse_data_idx_set() - */ -EAPI Eina_Bool -eina_matrixsparse_cell_data_set(Eina_Matrixsparse_Cell * cell, - const void *data) -{ - Eina_Matrixsparse *m; - - EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); - EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0); - EINA_MAGIC_CHECK_MATRIXSPARSE(cell->parent->parent, 0); - - m = cell->parent->parent; - - if (m->free.func) - m->free.func(m->free.user_data, cell->data); - - cell->data = (void *) data; - return 1; -} - -/** - * Change cell value without freeing the possibly existing old value, using - * indexes. - * - * @param m the sparse matrix, must @b not be @c NULL. - * @param row the row number to set the value. - * @param col the column number to set the value. - * @param data new data to set. - * @param p_old returns the old value intact (not freed). - * - * @return 1 on success, 0 otherwise (@a m is @c NULL, indexes are not valid). - * - * @see eina_matrixsparse_cell_data_replace() - * @see eina_matrixsparse_data_idx_set() - */ -EAPI Eina_Bool -eina_matrixsparse_data_idx_replace(Eina_Matrixsparse * m, - unsigned long row, - unsigned long col, - const void *data, void **p_old) -{ - Eina_Matrixsparse_Cell *cell; - - if (p_old) - *p_old = NULL; - - EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); - - cell = _eina_matrixsparse_cell_idx_get(m, row, col); - if (cell) { - if (p_old) - *p_old = cell->data; - - cell->data = (void *) data; - return 1; - } - - return _eina_matrixsparse_cell_idx_add(m, row, col, data); -} - -/** - * Change cell value freeing the possibly existing old value, using - * indexes. - * - * In contrast to eina_matrixsparse_data_idx_replace(), this function will - * call @c free_func() on existing value. - * - * @param m the sparse matrix, must @b not be @c NULL. - * @param row the row number to set the value. - * @param col the column number to set the value. - * @param data new data to set. - * - * @return 1 on success, 0 otherwise (@a m is @c NULL, indexes are not valid). - * - * @see eina_matrixsparse_cell_data_replace() - */ -EAPI Eina_Bool -eina_matrixsparse_data_idx_set(Eina_Matrixsparse * m, - unsigned long row, - unsigned long col, const void *data) -{ - Eina_Matrixsparse_Cell *cell; - - EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); - - cell = _eina_matrixsparse_cell_idx_get(m, row, col); - if (cell) { - if (m->free.func) - m->free.func(m->free.user_data, cell->data); - - cell->data = (void *) data; - return 1; - } - - return _eina_matrixsparse_cell_idx_add(m, row, col, data); -} - -/** - * Clear (erase all cells) of row given its index. - * - * Existing cells will be cleared with @c free_func() given to - * eina_matrixsparse_new(). - * - * @param m the sparse matrix to operate on. - * @param row the new number of row to clear. - * - * @return 1 on success, 0 on failure. It is considered success if row - * had no cells filled. Failure is asking for clear row outside - * matrix size. - * - * @warning cells, rows or columns are not reference counted and thus - * after this call any reference might be invalid if instance were - * freed. - */ -EAPI Eina_Bool -eina_matrixsparse_row_idx_clear(Eina_Matrixsparse * m, unsigned long row) -{ - Eina_Matrixsparse_Row *r; - - EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); - - r = _eina_matrixsparse_row_idx_get(m, row); - if (!r) - return 1; - - _eina_matrixsparse_row_unlink(r); - _eina_matrixsparse_row_free(r, m->free.func, m->free.user_data); - - return 1; -} - -/** - * Clear (erase all cells) of column given its index. - * - * Existing cells will be cleared with @c free_func() given to - * eina_matrixsparse_new(). - * - * @param m the sparse matrix to operate on. - * @param col the new number of column to clear. - * - * @return 1 on success, 0 on failure. It is considered success if column - * had no cells filled. Failure is asking for clear column outside - * matrix size. - * - * @warning cells, rows or columns are not reference counted and thus - * after this call any reference might be invalid if instance were - * freed. - */ -EAPI Eina_Bool -eina_matrixsparse_column_idx_clear(Eina_Matrixsparse * m, - unsigned long col) -{ - Eina_Matrixsparse_Row *r; - void (*free_func) (void *, void *); - void *user_data; - - EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); - - free_func = m->free.func; - user_data = m->free.user_data; - - for (r = m->rows; r;) { - Eina_Matrixsparse_Row *r_aux = r; - Eina_Matrixsparse_Cell *c; - - c = _eina_matrixsparse_row_cell_idx_get(r, col); - r = r->next; - - if (!c) - continue; - - if ((r_aux->cols != c) || (r_aux->last_col != c)) { - _eina_matrixsparse_cell_unlink(c); - _eina_matrixsparse_cell_free(c, free_func, - user_data); - } else { - _eina_matrixsparse_row_unlink(r_aux); - _eina_matrixsparse_row_free(r_aux, free_func, - user_data); - } - } - - return 1; -} - -/** - * Clear (erase) cell given its indexes. - * - * Existing cell will be cleared with @c free_func() given to - * eina_matrixsparse_new(). - * - * @param m the sparse matrix to operate on. - * @param row the new number of row to clear. - * @param col the new number of column to clear. - * - * @return 1 on success, 0 on failure. It is considered success if did not - * exist but index is inside matrix size. - * - * @warning cells, rows or columns are not reference counted and thus - * after this call any reference might be invalid if instance were - * freed. Note that this call might delete container column and - * row if this cell was the last remainder. - */ -EAPI Eina_Bool -eina_matrixsparse_cell_idx_clear(Eina_Matrixsparse * m, - unsigned long row, unsigned long col) -{ - Eina_Matrixsparse_Cell *c; - - EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); - EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); - - c = _eina_matrixsparse_cell_idx_get(m, row, col); - if (!c) - return 1; - - _eina_matrixsparse_cell_unlink(c); - _eina_matrixsparse_cell_free(c, m->free.func, m->free.user_data); - - return 1; -} - -/** - * Clear (erase) cell given its reference. - * - * @param cell the cell reference, must @b not be @c NULL. - * - * @return 1 on success, 0 on failure. - * - * @warning cells, rows or columns are not reference counted and thus - * after this call any reference might be invalid if instance were - * freed. Note that this call might delete container column and - * row if this cell was the last remainder. - */ -EAPI Eina_Bool eina_matrixsparse_cell_clear(Eina_Matrixsparse_Cell * cell) -{ - Eina_Matrixsparse *m; - - EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); - EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0); - EINA_MAGIC_CHECK_MATRIXSPARSE(cell->parent->parent, 0); - - m = cell->parent->parent; - - _eina_matrixsparse_cell_unlink(cell); - _eina_matrixsparse_cell_free(cell, m->free.func, - m->free.user_data); - return 1; -} - -/** - * Creates a new iterator over existing matrix cells. - * - * This is a cheap walk, it will just report existing cells and holes - * in the sparse matrix will be ignored. That means the reported - * indexes will not be sequential. - * - * The iterator data will be the cell reference, one may query current - * position with eina_matrixsparse_cell_position_get() and cell value - * with eina_matrixsparse_cell_data_get(). - * - * @param m The Sparse Matrix reference, must @b not be @c NULL. - * @return A new iterator. - * - * @warning if the matrix structure changes then the iterator becomes - * invalid! That is, if you add or remove cells this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_matrixsparse_iterator_new(const Eina_Matrixsparse - * m) -{ - Eina_Matrixsparse_Iterator *it; - - it = calloc(1, sizeof(*it)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(it, EINA_MAGIC_MATRIXSPARSE_ITERATOR); - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->m = m; - it->ref.row = m->rows; - it->ref.col = m->rows ? m->rows->cols : NULL; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = - FUNC_ITERATOR_NEXT(_eina_matrixsparse_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER - (_eina_matrixsparse_iterator_get_container); - it->iterator.free = - FUNC_ITERATOR_FREE(_eina_matrixsparse_iterator_free); - return &it->iterator; -} - -/** - * Creates a new iterator over all matrix cells. - * - * Unlike eina_matrixsparse_iterator_new() this one will report all - * matrix cells, even those that are still empty (holes). These will - * be reported as dummy cells that contains no data. - * - * Be aware that iterating a big matrix (1000x1000) will call your - * function that number of times (1000000 times in that case) even if - * your matrix have no elements at all! - * - * The iterator data will be the cell reference, one may query current - * position with eina_matrixsparse_cell_position_get() and cell value - * with eina_matrixsparse_cell_data_get(). If cell is empty then the - * reference will be a dummy/placeholder, thus setting value with - * eina_matrixsparse_cell_data_set() will leave pointer unreferenced. - * - * @param m The Sparse Matrix reference, must @b not be @c NULL. - * @return A new iterator. - * - * @warning if the matrix structure changes then the iterator becomes - * invalid! That is, if you add or remove cells this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_matrixsparse_iterator_complete_new(const - Eina_Matrixsparse - * m) -{ - Eina_Matrixsparse_Iterator_Complete *it; - - it = calloc(1, sizeof(*it)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(it, EINA_MAGIC_MATRIXSPARSE_ITERATOR); - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->m = m; - it->idx.row = 0; - it->idx.col = 0; - it->ref.row = m->rows; - it->ref.col = m->rows ? m->rows->cols : NULL; - - it->dummy.row.next = it->dummy.row.prev = NULL; - it->dummy.row.cols = it->dummy.row.last_col = - it->dummy.row.last_used = NULL; - it->dummy.row.parent = (Eina_Matrixsparse *) m; - EINA_MAGIC_SET(&it->dummy.row, EINA_MAGIC_MATRIXSPARSE_ROW); - - it->dummy.col.next = it->dummy.col.prev = NULL; - it->dummy.col.data = NULL; - it->dummy.col.parent = &it->dummy.row; - EINA_MAGIC_SET(&it->dummy.col, EINA_MAGIC_MATRIXSPARSE_CELL); - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = - FUNC_ITERATOR_NEXT(_eina_matrixsparse_iterator_complete_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER - (_eina_matrixsparse_iterator_complete_get_container); - it->iterator.free = - FUNC_ITERATOR_FREE(_eina_matrixsparse_iterator_complete_free); - return &it->iterator; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_mempool.c b/tests/suite/ecore/src/lib/eina_mempool.c deleted file mode 100644 index 8978720e29..0000000000 --- a/tests/suite/ecore/src/lib/eina_mempool.c +++ /dev/null @@ -1,393 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_hash.h" -#include "eina_module.h" -#include "eina_log.h" -#include "eina_main.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_mempool.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static Eina_Hash *_backends; -static Eina_Array *_modules; -static int _eina_mempool_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_mempool_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_mempool_log_dom, __VA_ARGS__) - - -static Eina_Mempool *_new_va(const char *name, - const char *context, - const char *options, va_list args) -{ - Eina_Mempool_Backend *be; - Eina_Mempool *mp; - - Eina_Error err = EINA_ERROR_NOT_MEMPOOL_MODULE; - - eina_error_set(0); - be = eina_hash_find(_backends, name); - if (!be) - goto on_error; - - err = EINA_ERROR_OUT_OF_MEMORY; - mp = calloc(1, sizeof(Eina_Mempool)); - if (!mp) - goto on_error; - - /* FIXME why backend is not a pointer? */ - mp->backend = *be; - mp->backend_data = mp->backend.init(context, options, args); - - return mp; - - on_error: - eina_error_set(err); - return NULL; -} - -/* Built-in backend's prototypes */ -#ifdef EINA_STATIC_BUILD_CHAINED_POOL -Eina_Bool chained_init(void); -void chained_shutdown(void); -#endif - -#ifdef EINA_STATIC_BUILD_PASS_THROUGH -Eina_Bool pass_through_init(void); -void pass_through_shutdown(void); -#endif - -#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN -Eina_Bool ememoa_unknown_init(void); -void ememoa_unknown_shutdown(void); -#endif - -#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED -Eina_Bool ememoa_fixed_init(void); -void ememoa_fixed_shutdown(void); -#endif - -#ifdef EINA_STATIC_BUILD_FIXED_BITMAP -Eina_Bool fixed_bitmap_init(void); -void fixed_bitmap_shutdown(void); -#endif - -#ifdef EINA_STATIC_BUILD_BUDDY -Eina_Bool buddy_init(void); -void buddy_shutdown(void); -#endif - -#ifdef EINA_STATIC_BUILD_ONE_BIG -Eina_Bool one_big_init(void); -void one_big_shutdown(void); -#endif - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -EAPI Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE = 0; - -static const char EINA_ERROR_NOT_MEMPOOL_MODULE_STR[] = - "Not a memory pool module."; - -/** - * @endcond - */ - -EAPI Eina_Bool eina_mempool_register(Eina_Mempool_Backend * be) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(be, 0); - DBG("be=%p, name=%p", be, be->name); - return eina_hash_add(_backends, be->name, be); -} - -EAPI void eina_mempool_unregister(Eina_Mempool_Backend * be) -{ - EINA_SAFETY_ON_NULL_RETURN(be); - DBG("be=%p, name=%p", be, be->name); - eina_hash_del(_backends, be->name, be); -} - -Eina_Bool eina_mempool_init(void) -{ - char *path; - - _eina_mempool_log_dom = eina_log_domain_register("eina_mempool", - EINA_LOG_COLOR_DEFAULT); - if (_eina_mempool_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_mempool"); - return 0; - } - - EINA_ERROR_NOT_MEMPOOL_MODULE = - eina_error_msg_static_register - (EINA_ERROR_NOT_MEMPOOL_MODULE_STR); - _backends = eina_hash_string_superfast_new(NULL); - - /* dynamic backends */ - _modules = eina_module_arch_list_get(NULL, - PACKAGE_LIB_DIR - "/eina/modules/mp", - MODULE_ARCH); - - path = - eina_module_environment_path_get("HOME", - "/.eina/mp/modules/mp"); - _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH); - if (path) - free(path); - - path = eina_module_environment_path_get("EINA_MODULES_MEMPOOL_DIR", - "/eina/modules/mp"); - _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH); - if (path) - free(path); - - path = eina_module_symbol_path_get((const void *) eina_init, - "/eina/modules/mp"); - _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH); - if (path) - free(path); - - if (!_modules) { - ERR("no mempool modules able to be loaded."); - eina_hash_free(_backends); - goto mempool_init_error; - } - - eina_module_list_load(_modules); - - /* builtin backends */ -#ifdef EINA_STATIC_BUILD_CHAINED_POOL - chained_init(); -#endif -#ifdef EINA_STATIC_BUILD_PASS_THROUGH - pass_through_init(); -#endif -#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN - ememoa_unknown_init(); -#endif -#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED - ememoa_fixed_init(); -#endif -#ifdef EINA_STATIC_BUILD_FIXED_BITMAP - fixed_bitmap_init(); -#endif -#ifdef EINA_STATIC_BUILD_BUDDY - buddy_init(); -#endif -#ifdef EINA_STATIC_BUILD_ONE_BIG - one_big_init(); -#endif - - return EINA_TRUE; - - mempool_init_error: - eina_log_domain_unregister(_eina_mempool_log_dom); - _eina_mempool_log_dom = -1; - - return EINA_FALSE; -} - -Eina_Bool eina_mempool_shutdown(void) -{ - /* builtin backends */ -#ifdef EINA_STATIC_BUILD_CHAINED_POOL - chained_shutdown(); -#endif -#ifdef EINA_STATIC_BUILD_PASS_THROUGH - pass_through_shutdown(); -#endif -#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN - ememoa_unknown_shutdown(); -#endif -#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED - ememoa_fixed_shutdown(); -#endif -#ifdef EINA_STATIC_BUILD_FIXED_BITMAP - fixed_bitmap_shutdown(); -#endif -#ifdef EINA_STATIC_BUILD_BUDDY - buddy_shutdown(); -#endif -#ifdef EINA_STATIC_BUILD_ONE_BIG - one_big_shutdown(); -#endif - /* dynamic backends */ - eina_module_list_free(_modules); - if (_modules) - eina_array_free(_modules); - - if (_backends) - eina_hash_free(_backends); - - eina_log_domain_unregister(_eina_mempool_log_dom); - _eina_mempool_log_dom = -1; - - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Memory_Pool_Group Memory Pool - * - * @brief These functions provide memory pool management. - * - * Several mempool are available: - * - * @li @c buddy: It uses the - * <a href="http://en.wikipedia.org/wiki/Buddy_memory_allocation">"buddy - * allocator" algorithm</a> but the Eina implementation differs in the - * sense that the chunk information is not stored on the chunk itself, - * but on another memory area. This is useful for cases where the - * memory to manage might be slower to access, or limited (like video - * memory). - * @li @c chained_pool: It is the default one. It allocates a big - * chunk of memory with malloc() and split the result in chunks of the - * requested size that are pushed inside a stack. When requested, it - * takes this pointer from the stack to give them to whoever wants - * them. - * @li @c ememoa_fixed and @c ememoa_unknown: experimental allocators - * which could be useful when a fixed amount of memory is needed. - * @li @c fixed_bitmap: It allocates with malloc) 32* the requested - * size and push the pool pointer in an rbtree. To find empty space in - * a pool, it will just search for the first bit set in an int (32 - * bits). Then, when a pointer is freed, it will do a search inside - * the rbtree. - * @li @c pass_through: it just call malloc() and free(). It may be - * faster on some computers than using our own allocators (like having - * a huge L2 cache, over 4MB). - * @li @c one_big: It call just one time malloc for the requested number - * of items. Usefull when you know in advance how many object of some - * type will live during the life of the mempool. - * - * @{ - */ - -EAPI Eina_Mempool *eina_mempool_add(const char *name, - const char *context, - const char *options, ...) -{ - Eina_Mempool *mp; - va_list args; - - EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); - DBG("name=%s, context=%s, options=%s", - name, context ? context : "", options ? options : ""); - - va_start(args, options); - mp = _new_va(name, context, options, args); - va_end(args); - - DBG("name=%s, context=%s, options=%s, mp=%p", - name, context ? context : "", options ? options : "", mp); - - return mp; -} - -EAPI void eina_mempool_del(Eina_Mempool * mp) -{ - EINA_SAFETY_ON_NULL_RETURN(mp); - EINA_SAFETY_ON_NULL_RETURN(mp->backend.shutdown); - DBG("mp=%p", mp); - mp->backend.shutdown(mp->backend_data); - free(mp); -} - -EAPI void eina_mempool_gc(Eina_Mempool * mp) -{ - EINA_SAFETY_ON_NULL_RETURN(mp); - EINA_SAFETY_ON_NULL_RETURN(mp->backend.garbage_collect); - DBG("mp=%p", mp); - mp->backend.garbage_collect(mp->backend_data); -} - -EAPI void eina_mempool_statistics(Eina_Mempool * mp) -{ - EINA_SAFETY_ON_NULL_RETURN(mp); - EINA_SAFETY_ON_NULL_RETURN(mp->backend.statistics); - DBG("mp=%p", mp); - mp->backend.statistics(mp->backend_data); -} - -EAPI unsigned int eina_mempool_alignof(unsigned int size) -{ - int align; - - if (size <= 2) - align = 2; - else if (size < 8) - align = 4; - else -#if __WORDSIZE == 32 - align = 8; - -#else - if (size < 16) - align = 8; - else - align = 16; -#endif - - return ((size / align) + 1) * align; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_module.c b/tests/suite/ecore/src/lib/eina_module.c deleted file mode 100644 index c47db1729a..0000000000 --- a/tests/suite/ecore/src/lib/eina_module.c +++ /dev/null @@ -1,750 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_DLADDR -#define _GNU_SOURCE -#endif - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#elif defined __GNUC__ -#define alloca __builtin_alloca -#elif defined _AIX -#define alloca __alloca -#elif defined _MSC_VER -#include <malloc.h> -#define alloca _alloca -#else -#include <stddef.h> -#ifdef __cplusplus -extern "C" -#endif -void *alloca(size_t); -#endif - -#include <stdio.h> -#include <sys/types.h> -#include <dirent.h> -#include <string.h> - -#ifndef _MSC_VER -#include <libgen.h> -#else -#include <Evil.h> -#endif - -#include <dlfcn.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_error.h" -#include "eina_file.h" -#include "eina_log.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_module.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static int EINA_MODULE_LOG_DOM = -1; -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(EINA_MODULE_LOG_DOM, __VA_ARGS__) - -#ifdef WRN -#undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(EINA_MODULE_LOG_DOM, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(EINA_MODULE_LOG_DOM, __VA_ARGS__) - -#define EINA_MODULE_SYMBOL_INIT "__eina_module_init" -#define EINA_MODULE_SYMBOL_SHUTDOWN "__eina_module_shutdown" - -struct _Eina_Module { - void *handle; - int ref; - const char file[]; -}; - -typedef struct _Dir_List_Get_Cb_Data { - Eina_Module_Cb cb; - void *data; - Eina_Array *array; -} Dir_List_Get_Cb_Data; - -typedef struct _Dir_List_Cb_Data { - Eina_Module_Cb cb; - void *data; -} Dir_List_Cb_Data; - -static Eina_Bool _dir_list_get_cb(Eina_Module * m, void *data) -{ - Dir_List_Get_Cb_Data *cb_data = data; - Eina_Bool ret = EINA_TRUE; - - if (cb_data->cb) - ret = cb_data->cb(m, cb_data->data); - - if (ret) - eina_array_push(cb_data->array, m); - - return ret; -} - -static void _dir_list_cb(const char *name, const char *path, void *data) -{ - Dir_List_Cb_Data *cb_data = data; - size_t length; - - length = strlen(name); - if (length < sizeof(SHARED_LIB_SUFFIX)) /* x.so */ - return; - - if (!strcmp(name + length - sizeof(SHARED_LIB_SUFFIX) + 1, - SHARED_LIB_SUFFIX)) { - char *file; - Eina_Module *m; - - length = strlen(path) + strlen(name) + 2; - - file = alloca(sizeof(char) * length); - if (!file) - return; - - snprintf(file, length, "%s/%s", path, name); - m = eina_module_new(file); - if (!m) { - return; /* call the user provided cb on this module */ - - } - - if (!cb_data->cb(m, cb_data->data)) - eina_module_free(m); - } -} - -static void _dir_arch_list_cb(const char *name, const char *path, - void *data) -{ - Dir_List_Get_Cb_Data *cb_data = data; - Eina_Module *m; - char *file = NULL; - size_t length; - - length = strlen(path) + 1 + strlen(name) + 1 + - strlen((char *) (cb_data->data)) + 1 + sizeof("module") + - sizeof(SHARED_LIB_SUFFIX) + 1; - - file = alloca(length); - snprintf(file, length, "%s/%s/%s/module" SHARED_LIB_SUFFIX, - path, name, (char *) (cb_data->data)); - m = eina_module_new(file); - if (!m) - return; - - eina_array_push(cb_data->array, m); -} - -/** - * @endcond - */ - - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -static const char EINA_ERROR_WRONG_MODULE_STR[] = - "Wrong file format or no file module found"; -static const char EINA_ERROR_MODULE_INIT_FAILED_STR[] = - "Module initialisation function failed"; - -EAPI Eina_Error EINA_ERROR_WRONG_MODULE = 0; -EAPI Eina_Error EINA_ERROR_MODULE_INIT_FAILED = 0; - -/** - * @endcond - */ - -/** - * @internal - * @brief Initialize the module loader module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the module loader module of Eina. It is - * called by eina_init(). - * - * This function sets up the module module of Eina. It also registers - * the errors #EINA_ERROR_WRONG_MODULE and - * #EINA_ERROR_MODULE_INIT_FAILED. - * - * @see eina_init() - */ -Eina_Bool eina_module_init(void) -{ - EINA_MODULE_LOG_DOM = eina_log_domain_register - ("eina_module", EINA_LOG_COLOR_DEFAULT); - if (EINA_MODULE_LOG_DOM < 0) { - EINA_LOG_ERR("Could not register log domain: eina_module"); - return EINA_FALSE; - } -#define EEMR(n) n = eina_error_msg_static_register(n ## _STR) - EEMR(EINA_ERROR_WRONG_MODULE); - EEMR(EINA_ERROR_MODULE_INIT_FAILED); -#undef EEMR - - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the module loader module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the module loader module set up by - * eina_module_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_module_shutdown(void) -{ - /* TODO should we store every module when "new" is called and - * delete the list of modules here - */ - - eina_log_domain_unregister(EINA_MODULE_LOG_DOM); - EINA_MODULE_LOG_DOM = -1; - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Module_Group Module - * - * @brief These functions provide module management. - * - * @{ - */ - -/** - * @brief Return a new module. - * - * @param file The name of the file module to load. - * - * This function returns a new module. If @p file is @c NULL, the - * function returns @c NULL, otherwise, it allocates an Eina_Module, - * stores a duplicate string of @p file, sets its reference to @c 0 - * and its handle to @c NULL. - * - * When the new module is not needed anymore, use eina_module_free() - * to free the allocated memory. - * - * @see eina_module_load - */ -EAPI Eina_Module *eina_module_new(const char *file) -{ - Eina_Module *m; - size_t len; - - EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); - /* TODO check that the file exists. Update doc too */ - - len = strlen(file); - EINA_SAFETY_ON_FALSE_RETURN_VAL(len > 0, NULL); - - m = malloc(sizeof(Eina_Module) + len + 1); - if (!m) { - ERR("could not malloc(%lu)", - (unsigned long) (sizeof(Eina_Module) + len + 1)); - return NULL; - } - - memcpy((char *) m->file, file, len + 1); - m->ref = 0; - m->handle = NULL; - DBG("m=%p, file=%s", m, file); - - return m; -} - -/** - * @brief Delete a module. - * - * @param m The module to delete. - * @return EINA_TRUE on success, EINA_FALSE otherwise. - * - * This function calls eina_module_unload() if @p m has been previously - * loaded and frees the allocated memory. On success this function - * returns EINA_TRUE and EINA_FALSE otherwise. If @p m is @c NULL, the - * function returns immediately. - */ -EAPI Eina_Bool eina_module_free(Eina_Module * m) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); - - DBG("m=%p, handle=%p, file=%s, refs=%d", m, m->handle, m->file, - m->ref); - - if (m->handle) - if (eina_module_unload(m) == EINA_FALSE) - return EINA_FALSE; - - free(m); - return EINA_TRUE; -} - -/** - * @brief Load a module. - * - * @param m The module to load. - * @return EINA_TRUE on success, EINA_FALSE otherwise. - * - * This function load the shared file object passed in - * eina_module_new(). If it is a internal Eina module (like the - * mempools), it also initialize it. It the shared file object can not - * be loaded, the error #EINA_ERROR_WRONG_MODULE is set and - * #EINA_FALSE is returned. If it is a internal Eina module and the - * module can not be initialized, the error - * #EINA_ERROR_MODULE_INIT_FAILED is set and #EINA_FALSE is - * returned. If the module has already been loaded, it's refeence - * counter is increased by one and #EINA_TRUE is returned. If @p m is - * @c NULL, the function returns immediately #EINA_FALSE. - * - * When the symbols of the shared file objetcts are not needed - * anymore, call eina_module_unload() to unload the module. - */ -EAPI Eina_Bool eina_module_load(Eina_Module * m) -{ - void *dl_handle; - Eina_Module_Init *initcall; - - EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); - - DBG("m=%p, handle=%p, file=%s, refs=%d", m, m->handle, m->file, - m->ref); - - if (m->handle) - goto loaded; - - dl_handle = dlopen(m->file, RTLD_NOW); - if (!dl_handle) { - WRN("could not dlopen(\"%s\", RTLD_NOW): %s", m->file, - dlerror()); - eina_error_set(EINA_ERROR_WRONG_MODULE); - return EINA_FALSE; - } - - initcall = dlsym(dl_handle, EINA_MODULE_SYMBOL_INIT); - if ((!initcall) || (!(*initcall))) - goto ok; - - if ((*initcall) () == EINA_TRUE) - goto ok; - - WRN("could not find eina's entry symbol %s inside module %s", - EINA_MODULE_SYMBOL_INIT, m->file); - eina_error_set(EINA_ERROR_MODULE_INIT_FAILED); - dlclose(dl_handle); - return EINA_FALSE; - ok: - DBG("successfully loaded %s", m->file); - m->handle = dl_handle; - loaded: - m->ref++; - DBG("ref %d", m->ref); - - eina_error_set(0); - return EINA_TRUE; -} - -/** - * @brief Unload a module. - * - * @param m The module to load. - * @return EINA_TRUE on success, EINA_FALSE otherwise. - * - * This function unload the module @p m that has been previously - * loaded by eina_module_load(). If the reference counter of @p m is - * strictly greater than @c 1, #EINA_FALSE is returned. Otherwise, the - * shared object file is closed and if it is a internal Eina module, it - * is shutted down just before. In that case, #EINA_TRUE is - * returned. In all case, the reference counter is decreased. If @p m - * is @c NULL, the function returns immediately #EINA_FALSE. - */ -EAPI Eina_Bool eina_module_unload(Eina_Module * m) -{ - Eina_Module_Shutdown *shut; - EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); - - DBG("m=%p, handle=%p, file=%s, refs=%d", m, m->handle, m->file, - m->ref); - - m->ref--; - if (!m->ref) { - shut = dlsym(m->handle, EINA_MODULE_SYMBOL_SHUTDOWN); - if ((shut) && (*shut)) - (*shut) (); - - dlclose(m->handle); - m->handle = NULL; - DBG("unloaded module %s", m->file); - return EINA_TRUE; - } - - return EINA_FALSE; -} - -/** - * @brief Retrive the data associated to a symbol. - * - * @param m The module. - * @param symbol The symbol. - * @return The data associated to the symbol, or @c NULL on failure. - * - * This function returns the data associated to @p symbol of @p m. @p - * m must have been loaded before with eina_module_load(). If @p m - * is @c NULL, or if it has not been correctly loaded before, the - * function returns immediately @c NULL. - */ -EAPI void *eina_module_symbol_get(const Eina_Module * m, - const char *symbol) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(m->handle, NULL); - return dlsym(m->handle, symbol); -} - -/** - * @brief Return the file name associated to the module. - * - * @param m The module. - * @return The file name. - * - * This function returns the file name passed in eina_module_new(). If - * @p m is @c NULL, the function returns immediately @c NULL. The - * returned value must no be freed. - */ -EAPI const char *eina_module_file_get(const Eina_Module * m) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); - return m->file; -} - -/** - * @brief Return the path built from the location of a library and a - * given sub directory. - * - * @param symbol The symbol to search for. - * @param sub_dir The subdirectory to append. - * @return The built path on success, @c NULL otherwise. - * - * This function returns the path built by concatenating the path of - * the library containing the symbol @p symbol and @p sub_dir. @p sub_dir - * can be @c NULL. The returned path must be freed when not used - * anymore. If the symbol is not found, or dl_addr() is not supported, - * or allocation fails, this function returns @c NULL. - */ -EAPI char *eina_module_symbol_path_get(const void *symbol, - const char *sub_dir) -{ -#ifdef HAVE_DLADDR - Dl_info eina_dl; - - EINA_SAFETY_ON_NULL_RETURN_VAL(symbol, NULL); - - if (dladdr(symbol, &eina_dl)) { - char *pos = strrchr(eina_dl.dli_fname, '/'); - if (pos) { - char *path; - int l0; - int l1; - int l2 = 0; - - l0 = strlen(eina_dl.dli_fname); - l1 = strlen(pos); - if (sub_dir && (*sub_dir != '\0')) - l2 = strlen(sub_dir); - - path = malloc(l0 - l1 + l2 + 1); - if (path) { - memcpy(path, eina_dl.dli_fname, l0 - l1); - if (sub_dir && (*sub_dir != '\0')) - memcpy(path + l0 - l1, sub_dir, - l2); - - path[l0 - l1 + l2] = '\0'; - return path; - } - } - } -#endif /* ! HAVE_DLADDR */ - - return NULL; -} - -/** - * @brief Return the path built from the value of an environment varialbe and a - * given sub directory. - * - * @param env The environment variable to expand. - * @param sub_dir The subdirectory to append. - * @return The built path on success, @c NULL otherwise. - * - * This function returns the path built by concatenating the value of - * the environment variable named @p env and @p sub_dir. @p sub_dir - * can be @c NULL. The returned path must be freed when not used - * anymore. If the symbol is not found, or @p env does not exist, or - * allocation fails, this function returns @c NULL. - */ -EAPI char *eina_module_environment_path_get(const char *env, - const char *sub_dir) -{ - const char *env_dir; - - EINA_SAFETY_ON_NULL_RETURN_VAL(env, NULL); - - env_dir = getenv(env); - if (env_dir) { - char *path; - size_t l1; - size_t l2 = 0; - - l1 = strlen(env_dir); - if (sub_dir && (*sub_dir != '\0')) - l2 = strlen(sub_dir); - - path = (char *) malloc(l1 + l2 + 1); - if (path) { - memcpy(path, env_dir, l1); - if (sub_dir && (*sub_dir != '\0')) - memcpy(path + l1, sub_dir, l2); - - path[l1 + l2] = '\0'; - - return path; - } - } - - return NULL; -} - -/** - * @brief Get an array of modules found on the directory path matching an arch type. - * - * @param array The array that stores the list of the modules. - * @param path The directory's path to search for modules. - * @param arch The architecture string. - * - * This function adds to @p array the module names found in @p path - * which match the cpu architecture @p arch. If @p path or @p arch is - * @c NULL, the function returns immediately @p array. @p array can be - * @c NULL. In that case, it is created with 4 elements. - */ -EAPI Eina_Array *eina_module_arch_list_get(Eina_Array * array, - const char *path, - const char *arch) -{ - Dir_List_Get_Cb_Data list_get_cb_data; - - if ((!path) || (!arch)) - return array; - - list_get_cb_data.array = array ? array : eina_array_new(4); - list_get_cb_data.cb = NULL; - list_get_cb_data.data = (void *) arch; - - eina_file_dir_list(path, 0, &_dir_arch_list_cb, &list_get_cb_data); - - return list_get_cb_data.array; -} - -/** - * @brief Get a list of modules found on the directory path. - * - * @param array The array that stores the list of the modules. - * @param path The directory's path to search for modules. - * @param recursive Iterate recursively on the path. - * @param cb Callback function to call on each module. - * @param data Data passed to the callback function. - * - * This function adds to @p array the list of modules found in - * @p path. If @p recursive is #EINA_TRUE, then recursive search is - * done. The callback @p cb is called on each module found, and @p data - * is passed to @p cb. If @p path is @c NULL, the function returns - * immediately @p array. If the returned value of @p cb is 0, the - * module will not be added to the list, otherwise it will be added. - * @p array can be @c NULL. In that case, it is created with 4 - * elements. @p cb can be @c NULL. - */ -EAPI Eina_Array *eina_module_list_get(Eina_Array * array, - const char *path, - Eina_Bool recursive, - Eina_Module_Cb cb, void *data) -{ - Dir_List_Get_Cb_Data list_get_cb_data; - Dir_List_Cb_Data list_cb_data; - - if (!path) - return array; - - list_get_cb_data.array = array ? array : eina_array_new(4); - list_get_cb_data.cb = cb; - list_get_cb_data.data = data; - - list_cb_data.cb = &_dir_list_get_cb; - list_cb_data.data = &list_get_cb_data; - - eina_file_dir_list(path, recursive, &_dir_list_cb, &list_cb_data); - - return list_get_cb_data.array; -} - -/** - * @brief Find an module in array. - * - * @param array The array to find the module. - * @param module The name of module to be searched. - * - * This function finds an @p module in @p array. - * If the element is found the function returns the module, else - * @c NULL is returned. - */ -EAPI Eina_Module *eina_module_find(const Eina_Array * array, - const char *module) -{ - unsigned int i; - Eina_Array_Iterator iterator; - Eina_Module *m; - - EINA_ARRAY_ITER_NEXT(array, i, m, iterator) { - char *file_m; - char *tmp; - ssize_t len; - - /* basename() can modify its argument, so we first get a copie */ - /* do not use strdupa, as opensolaris does not have it */ - len = strlen(eina_module_file_get(m)); - tmp = alloca(len + 1); - memcpy(tmp, eina_module_file_get(m), len + 1); - file_m = basename(tmp); - len = strlen(file_m); - len -= sizeof(SHARED_LIB_SUFFIX) - 1; - if (len <= 0) - continue; - - if (!strncmp(module, file_m, len)) - return m;; - } - - return NULL; -} - -/** - * @brief Load every module on the list of modules. - * - * @param array The array of modules to load. - * - * This function calls eina_module_load() on each element found in - * @p array. If @p array is @c NULL, this function does nothing. - */ -EAPI void eina_module_list_load(Eina_Array * array) -{ - Eina_Array_Iterator iterator; - Eina_Module *m; - unsigned int i; - - EINA_SAFETY_ON_NULL_RETURN(array); - DBG("array %p, count %u", array, array->count); - EINA_ARRAY_ITER_NEXT(array, i, m, iterator) - eina_module_load(m); -} - -/** - * @brief Unload every module on the list of modules. - * - * @param array The array of modules to unload. - * - * This function calls eina_module_unload() on each element found in - * @p array. If @p array is @c NULL, this function does nothing. - */ -EAPI void eina_module_list_unload(Eina_Array * array) -{ - Eina_Array_Iterator iterator; - Eina_Module *m; - unsigned int i; - - EINA_SAFETY_ON_NULL_RETURN(array); - DBG("array %p, count %u", array, array->count); - EINA_ARRAY_ITER_NEXT(array, i, m, iterator) - eina_module_unload(m); -} - -/** - * @p Free every module on the list of modules. - * - * @param array The array of modules to free. - * - * This function calls eina_module_free() on each element found in - * @p array. If @p array is @c NULL, this function does nothing. - */ -EAPI void eina_module_list_free(Eina_Array * array) -{ - Eina_Array_Iterator iterator; - Eina_Module *m; - unsigned int i; - - EINA_SAFETY_ON_NULL_RETURN(array); - DBG("array %p, count %u", array, array->count); - EINA_ARRAY_ITER_NEXT(array, i, m, iterator) - eina_module_free(m); - - eina_array_flush(array); -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_private.h b/tests/suite/ecore/src/lib/eina_private.h deleted file mode 100644 index 18ab5bd989..0000000000 --- a/tests/suite/ecore/src/lib/eina_private.h +++ /dev/null @@ -1,134 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008 Carsten Haitzler, Vincent Torri, Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifndef EINA_PRIVATE_H_ -#define EINA_PRIVATE_H_ - -#include <stdarg.h> - -#if HAVE___ATTRIBUTE__ -#define __UNUSED__ __attribute__((unused)) -#else -#define __UNUSED__ -#endif - -#include "eina_magic.h" -#include "eina_iterator.h" -#include "eina_accessor.h" - -#ifndef MIN -#define MIN(x, y) (((x) > (y)) ? (y) : (x)) -#endif - -#ifndef MAX -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) -#endif - -#ifndef ABS -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#endif - -#ifndef CLAMP -#define CLAMP(x, min, \ - max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x))) -#endif - -#define READBUFSIZ 65536 - -#define EINA_LOG_COLOR_DEFAULT "\033[36m" - -/* eina magic types */ -#define EINA_MAGIC_SHARE 0x98761234 -#define EINA_MAGIC_SHARE_HEAD 0x98761235 -#define EINA_MAGIC_STRINGSHARE_NODE 0x98761254 -#define EINA_MAGIC_USTRINGSHARE_NODE 0x98761255 -#define EINA_MAGIC_BINSHARE_NODE 0x98761256 - -#define EINA_MAGIC_LIST 0x98761237 -#define EINA_MAGIC_LIST_ITERATOR 0x98761238 -#define EINA_MAGIC_LIST_ACCESSOR 0x98761239 -#define EINA_MAGIC_LIST_ACCOUNTING 0x9876123a - -#define EINA_MAGIC_ARRAY 0x9876123b -#define EINA_MAGIC_ARRAY_ITERATOR 0x9876123c -#define EINA_MAGIC_ARRAY_ACCESSOR 0x9876123d - -#define EINA_MAGIC_HASH 0x9876123e -#define EINA_MAGIC_HASH_ITERATOR 0x9876123f - -#define EINA_MAGIC_TILER 0x98761240 -#define EINA_MAGIC_TILER_ITERATOR 0x98761241 - -#define EINA_MAGIC_MATRIXSPARSE 0x98761242 -#define EINA_MAGIC_MATRIXSPARSE_ROW 0x98761243 -#define EINA_MAGIC_MATRIXSPARSE_CELL 0x98761244 -#define EINA_MAGIC_MATRIXSPARSE_ITERATOR 0x98761245 -#define EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR 0x98761246 -#define EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR 0x98761247 -#define EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR 0x98761248 -#define EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR 0x98761249 - -#define EINA_MAGIC_STRBUF 0x98761250 -#define EINA_MAGIC_USTRBUF 0x98761257 - -#define EINA_MAGIC_QUADTREE 0x98761251 -#define EINA_MAGIC_QUADTREE_ROOT 0x98761252 -#define EINA_MAGIC_QUADTREE_ITEM 0x98761253 - -/* undef the following, we want out version */ -#undef FREE -#define FREE(ptr) \ - do { \ - free(ptr); \ - ptr = NULL; \ - } while(0); - -#undef IF_FREE -#define IF_FREE(ptr) \ - do { \ - if (ptr) { \ - free(ptr); \ - ptr = NULL; \ - } \ - } while(0); - -#undef IF_FN_DEL -#define IF_FN_DEL(_fn, ptr) \ - do { \ - if (ptr) { \ - _fn(ptr); \ - ptr = NULL; \ - } \ - } while(0); - -#define MAGIC_FREE(ptr) \ - do { \ - if (ptr) { \ - EINA_MAGIC_SET(ptr, EINA_MAGIC_NONE); \ - FREE(ptr); \ - } \ - } while(0); - -#ifdef EFL_HAVE_THREADS -void eina_share_common_threads_init(void); -void eina_share_common_threads_shutdown(void); -void eina_log_threads_init(void); -void eina_log_threads_shutdown(void); -#endif - -#endif /* EINA_PRIVATE_H_ */ diff --git a/tests/suite/ecore/src/lib/eina_quadtree.c b/tests/suite/ecore/src/lib/eina_quadtree.c deleted file mode 100644 index a4cc4486a0..0000000000 --- a/tests/suite/ecore/src/lib/eina_quadtree.c +++ /dev/null @@ -1,908 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -/** - * @page tutorial_quadtree_page QuadTree Tutorial - * - * to be written... - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> - -#include "eina_quadtree.h" -#include "eina_magic.h" -#include "eina_mempool.h" -#include "eina_list.h" -#include "eina_inlist.h" -#include "eina_trash.h" -#include "eina_log.h" -#include "eina_rectangle.h" - -#include "eina_private.h" - -typedef struct _Eina_QuadTree_Root Eina_QuadTree_Root; - -static const char EINA_MAGIC_QUADTREE_STR[] = "Eina QuadTree"; -static const char EINA_MAGIC_QUADTREE_ROOT_STR[] = "Eina QuadTree Root"; -static const char EINA_MAGIC_QUADTREE_ITEM_STR[] = "Eina QuadTree Item"; - -#define EINA_MAGIC_CHECK_QUADTREE(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_QUADTREE)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_QUADTREE); \ - return __VA_ARGS__; \ - } \ - } while(0); - -#define EINA_MAGIC_CHECK_QUADTREE_ROOT(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_QUADTREE_ROOT)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_QUADTREE_ROOT); \ - return __VA_ARGS__; \ - } \ - } while(0); - -#define EINA_MAGIC_CHECK_QUADTREE_ITEM(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_QUADTREE_ITEM)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_QUADTREE_ITEM); \ - return __VA_ARGS__; \ - } \ - } while(0); - -struct _Eina_QuadTree { - EINA_MAGIC; - - Eina_QuadTree_Root *root; - - Eina_List *hidden; - - size_t root_count; - size_t items_count; - - Eina_Trash *items_trash; - Eina_Trash *root_trash; - - Eina_Inlist *change; - Eina_Inlist *cached; - Eina_Rectangle target; - - size_t index; - - struct { - Eina_Quad_Callback v; - Eina_Quad_Callback h; - } func; - - struct { - size_t w; - size_t h; - } geom; - - Eina_Bool resize:1; - Eina_Bool lost:1; -}; - -struct _Eina_QuadTree_Root { - EINA_MAGIC; - - Eina_QuadTree_Root *parent; - Eina_QuadTree_Root *left; - Eina_QuadTree_Root *right; - - Eina_List *both; - - Eina_Bool sorted:1; -}; - -struct _Eina_QuadTree_Item { - EINA_MAGIC; - EINA_INLIST; - - Eina_QuadTree *quad; - Eina_QuadTree_Root *root; - - const void *object; - - size_t index; - - Eina_Bool change:1; - Eina_Bool delete_me:1; - Eina_Bool visible:1; - Eina_Bool hidden:1; -}; - -static int _eina_log_qd_dom = -1; -static Eina_Mempool *root_mp = NULL; -static Eina_Mempool *items_mp = NULL; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_log_qd_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_log_qd_dom, __VA_ARGS__) - - -static int _eina_quadtree_item_cmp(const void *a, const void *b) -{ - const Eina_QuadTree_Item *i = a; - const Eina_QuadTree_Item *j = b; - - return i->index - j->index; -} - -static Eina_QuadTree_Root *eina_quadtree_root_free(Eina_QuadTree * q, - Eina_QuadTree_Root * - root) -{ - Eina_QuadTree_Item *item; - - if (!root) - return NULL; - - EINA_MAGIC_CHECK_QUADTREE_ROOT(root, NULL); - - EINA_LIST_FREE(root->both, item) - eina_mempool_free(items_mp, item); - - root->left = eina_quadtree_root_free(q, root->left); - root->right = eina_quadtree_root_free(q, root->right); - - EINA_MAGIC_SET(root, 0); - eina_mempool_free(root_mp, root); - - return NULL; -} - -static Eina_QuadTree_Root *eina_quadtree_root_rebuild_pre(Eina_QuadTree * - q, - Eina_Inlist ** - change, - Eina_QuadTree_Root - * root) -{ - Eina_QuadTree_Item *item; - - if (!root) - return NULL; - - EINA_LIST_FREE(root->both, item) { - if (item->visible) - *change = - eina_inlist_append(*change, - EINA_INLIST_GET(item)); - else if (!item->hidden) { - q->hidden = eina_list_append(q->hidden, item); - item->hidden = EINA_TRUE; - item->root = NULL; - } - } - - root->left = eina_quadtree_root_rebuild_pre(q, change, root->left); - root->right = - eina_quadtree_root_rebuild_pre(q, change, root->right); - - EINA_MAGIC_SET(root, 0); - if (q->root_count > 50) - eina_mempool_free(root_mp, root); - else { - eina_trash_push(&q->root_trash, root); - q->root_count++; - } - - return NULL; -} - -static size_t -_eina_quadtree_split(Eina_Inlist * objects, - Eina_QuadTree_Root * root, - Eina_Inlist ** left, - Eina_Inlist ** right, - Eina_Quad_Callback func, int border, int middle) -{ - Eina_QuadTree_Item *object; - - middle /= 2; - - if (middle <= 4) - while (objects) { - object = - EINA_INLIST_CONTAINER_GET(objects, - Eina_QuadTree_Item); - objects = objects->next; - - object->change = EINA_FALSE; - if (!object->visible) { - if (!object->hidden) { - object->hidden = EINA_TRUE; - object->quad->hidden = - eina_list_append(object->quad-> - hidden, - object); - } - - continue; - } - - if (object->hidden) { - object->hidden = EINA_FALSE; - object->quad->hidden = - eina_list_remove(object->quad->hidden, - object); - } - - if (!object->delete_me) { - if (root->sorted) - root->both = - eina_list_sorted_insert(root-> - both, - _eina_quadtree_item_cmp, - object); - else - root->both = - eina_list_append(root->both, - object); - - object->root = root; - } else - eina_quadtree_del(object); - } else - while (objects) { - object = - EINA_INLIST_CONTAINER_GET(objects, - Eina_QuadTree_Item); - objects = objects->next; - - object->change = EINA_FALSE; - if (!object->visible) { - if (!object->hidden) { - object->hidden = EINA_TRUE; - object->quad->hidden = - eina_list_append(object->quad-> - hidden, - object); - } - - continue; - } - - if (object->hidden) { - object->hidden = EINA_FALSE; - object->quad->hidden = - eina_list_remove(object->quad->hidden, - object); - } - - if (!object->delete_me) { - switch (func - (object->object, - border + middle)) { - case EINA_QUAD_LEFT: - *left = - eina_inlist_append(*left, - EINA_INLIST_GET - (object)); - break; - - case EINA_QUAD_RIGHT: - *right = - eina_inlist_append(*right, - EINA_INLIST_GET - (object)); - break; - - case EINA_QUAD_BOTH: - root->both = - eina_list_append(root->both, - object); - object->root = root; - break; - - default: - abort(); - } - } else - eina_quadtree_del(object); - } - - return middle; -} - - -static Eina_QuadTree_Root *_eina_quadtree_update(Eina_QuadTree * q, - Eina_QuadTree_Root * - parent, - Eina_QuadTree_Root * root, - Eina_Inlist * objects, - Eina_Bool direction, - Eina_Rectangle * size) -{ - Eina_Inlist *right = NULL; - Eina_Inlist *left = NULL; - size_t w2; - size_t h2; - - if (!objects) - return root; - - if (!root) { - root = eina_trash_pop(&q->root_trash); - if (!root) - root = - eina_mempool_malloc(root_mp, - sizeof - (Eina_QuadTree_Root)); - else - q->root_count--; - - if (!root) - /* FIXME: NOT GOOD TIMING, WE ARE GOING TO LEAK MORE MEMORY */ - return NULL; - - root->parent = parent; - root->both = NULL; - root->left = NULL; - root->right = NULL; - root->sorted = EINA_TRUE; - - EINA_MAGIC_SET(root, EINA_MAGIC_QUADTREE_ROOT); - } - - w2 = 0; - h2 = 0; - - if (direction) - w2 = _eina_quadtree_split(objects, root, - &left, &right, - q->func.h, size->x, size->w); - else - h2 = _eina_quadtree_split(objects, root, - &left, &right, - q->func.v, size->y, size->h); - - size->w -= w2; - size->h -= h2; - root->left = _eina_quadtree_update(q, root, - root->left, left, - !direction, size); - size->x += w2; - size->y += h2; - root->right = _eina_quadtree_update(q, root, - root->right, right, - !direction, size); - size->x -= w2; - size->y -= h2; - size->w += w2; - size->h += h2; - - return root; -} - -static Eina_Inlist *_eina_quadtree_merge(Eina_Inlist * result, - Eina_List * both) -{ - Eina_QuadTree_Item *item; - Eina_QuadTree_Item *b; - Eina_Inlist *moving; - - if (!both) - return result; - - if (!result) { - Eina_List *l; - - EINA_LIST_FOREACH(both, l, item) - if (item->visible) - result = - eina_inlist_append(result, - EINA_INLIST_GET(item)); - - return result; - } - - moving = result; - - item = EINA_INLIST_CONTAINER_GET(moving, Eina_QuadTree_Item); - b = eina_list_data_get(both); - - while (both && moving) { - if (!b->visible) { - both = eina_list_next(both); - b = eina_list_data_get(both); - continue; - } - - if (_eina_quadtree_item_cmp(item, b) < 0) { - /* moving is still lower than item, so we can continue to the next one. */ - moving = moving->next; - item = - EINA_INLIST_CONTAINER_GET(moving, - Eina_QuadTree_Item); - } else { - /* we just get above the limit of both, so insert it */ - result = eina_inlist_prepend_relative(result, - EINA_INLIST_GET - (b), moving); - both = eina_list_next(both); - b = eina_list_data_get(both); - } - } - - item = EINA_INLIST_CONTAINER_GET(result->last, Eina_QuadTree_Item); - - while (both) { - b = eina_list_data_get(both); - if (b->visible) { - if (_eina_quadtree_item_cmp(item, b) < 0) - break; - - result = eina_inlist_prepend_relative(result, - EINA_INLIST_GET - (b), - result-> - last); - } - - both = eina_list_next(both); - } - - while (both) { - b = eina_list_data_get(both); - if (b->visible) - result = - eina_inlist_append(result, EINA_INLIST_GET(b)); - - both = eina_list_next(both); - } - - return result; -} - -static Eina_Inlist *_eina_quadtree_collide(Eina_Inlist * result, - Eina_QuadTree_Root * root, - Eina_Bool direction, - Eina_Rectangle * size, - Eina_Rectangle * target) -{ - if (!root) - return result; - - if (!root->sorted) { - root->both = - eina_list_sort(root->both, -1, - _eina_quadtree_item_cmp); - root->sorted = EINA_TRUE; - } - - result = _eina_quadtree_merge(result, root->both); - DBG("%p: %i in both for (%i, %i - %i, %i)", - root, eina_list_count(root->both), - size->x, size->y, size->w, size->h); - - if (direction) { - int middle = size->w / 2; - - size->w -= middle; - if (eina_spans_intersect - (size->x, size->w, target->x, target->w)) - result = - _eina_quadtree_collide(result, root->left, - !direction, size, - target); - - size->x += middle; - if (eina_spans_intersect - (size->x, size->w, target->x, target->w)) - result = - _eina_quadtree_collide(result, root->right, - !direction, size, - target); - - size->x -= middle; - size->w += middle; - } else { - int middle = size->h / 2; - - size->h -= middle; - if (eina_spans_intersect - (size->y, size->h, target->y, target->h)) - result = - _eina_quadtree_collide(result, root->left, - !direction, size, - target); - - size->y += middle; - if (eina_spans_intersect - (size->y, size->h, target->y, target->h)) - result = - _eina_quadtree_collide(result, root->right, - !direction, size, - target); - - size->y -= middle; - size->h += middle; - } - - return result; -} - -static void _eina_quadtree_remove(Eina_QuadTree_Item * object) -{ - if (!object->root) - return; - - object->root->both = eina_list_remove(object->root->both, object); - if (object->root->both) - goto end; - - if (object->root->left) - goto end; - - if (object->root->right) - goto end; - - /* The root is not useful anymore... */ - if (object->root->parent) { - if (object->root->parent->left == object->root) - object->root->parent->left = NULL; - else - object->root->parent->right = NULL; - - object->root->parent = NULL; - } else - object->quad->root = NULL; - - if (object->quad->root_count > 50) - eina_mempool_free(root_mp, object->root); - else { - eina_trash_push(&object->quad->root_trash, object->root); - object->quad->root_count++; - } - - end: - object->root = NULL; -} - -EAPI Eina_QuadTree *eina_quadtree_new(size_t w, size_t h, - Eina_Quad_Callback vertical, - Eina_Quad_Callback horizontal) -{ - Eina_QuadTree *result; - - if (!vertical || !horizontal || h == 0 || w == 0) - return NULL; - - result = calloc(1, sizeof(Eina_QuadTree)); - if (!result) - return NULL; - - result->func.v = vertical; - result->func.h = horizontal; - - result->geom.w = w; - result->geom.h = h; - - result->change = NULL; - - result->lost = EINA_TRUE; - - EINA_MAGIC_SET(result, EINA_MAGIC_QUADTREE); - - return result; -} - -EAPI void eina_quadtree_free(Eina_QuadTree * q) -{ - Eina_QuadTree_Item *item; - - if (!q) - return; - - EINA_MAGIC_CHECK_QUADTREE(q); - - while (q->change) { - item = - EINA_INLIST_CONTAINER_GET(q->change, - Eina_QuadTree_Item); - q->change = q->change->next; - if (!item->hidden) - eina_mempool_free(items_mp, item); - } - - EINA_LIST_FREE(q->hidden, item) - eina_mempool_free(items_mp, item); - - eina_quadtree_root_free(q, q->root); - - while (q->items_trash) { - item = eina_trash_pop(&q->items_trash); - eina_mempool_free(items_mp, item); - } - - while (q->root_trash) { - Eina_QuadTree_Root *root; - - root = eina_trash_pop(&q->root_trash); - eina_mempool_free(root_mp, root); - } - - EINA_MAGIC_SET(q, 0); - free(q); -} - -EAPI Eina_QuadTree_Item *eina_quadtree_add(Eina_QuadTree * q, - const void *object) -{ - Eina_QuadTree_Item *result; - - EINA_MAGIC_CHECK_QUADTREE(q, NULL); - - if (!object) - return NULL; - - result = eina_trash_pop(&q->items_trash); - if (!result) - result = - eina_mempool_malloc(items_mp, - sizeof(Eina_QuadTree_Item)); - else - q->items_count--; - - if (!result) - return NULL; - - result->quad = q; - result->root = NULL; - result->object = object; - - result->index = q->index++; - - result->change = EINA_TRUE; - result->delete_me = EINA_FALSE; - result->visible = EINA_TRUE; - result->hidden = EINA_FALSE; - - EINA_MAGIC_SET(result, EINA_MAGIC_QUADTREE_ITEM); - - /* Insertion is delayed until we really need to use it */ - q->change = eina_inlist_append(q->change, EINA_INLIST_GET(result)); - - return result; -} - -EAPI Eina_Bool eina_quadtree_del(Eina_QuadTree_Item * object) -{ - if (!object) - return EINA_FALSE; - - EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); - - _eina_quadtree_remove(object); - - if (object->change) { - /* This object is still in the update array, delaying it's removal ! */ - object->delete_me = EINA_TRUE; - object->visible = EINA_TRUE; - return EINA_TRUE; - } - - if (object->hidden) { - object->quad->hidden = - eina_list_remove(object->quad->hidden, object); - object->hidden = EINA_TRUE; - } - - /* This object is not anymore inside the tree, we can remove it now ! */ - EINA_MAGIC_SET(object, 0); - if (object->quad->items_count > 256) - eina_mempool_free(items_mp, object); - else { - object->quad->items_count++; - eina_trash_push(&object->quad->items_trash, object); - } - - return EINA_TRUE; -} - -EAPI Eina_Bool eina_quadtree_change(Eina_QuadTree_Item * object) -{ - EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); - - if (object->delete_me || !object->visible) - return EINA_FALSE; - - if (object->quad->resize) - return EINA_TRUE; - - /* Delaying change until needed */ - if (!object->change) - object->quad->change = - eina_inlist_append(object->quad->change, - EINA_INLIST_GET(object)); - - object->change = EINA_TRUE; - - _eina_quadtree_remove(object); - - return EINA_TRUE; -} - -EAPI Eina_Bool eina_quadtree_hide(Eina_QuadTree_Item * object) -{ - EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); - - object->visible = EINA_FALSE; - - return EINA_TRUE; -} - -EAPI Eina_Bool eina_quadtree_show(Eina_QuadTree_Item * object) -{ - EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); - - object->quad->lost = EINA_TRUE; - - if (object->visible) - return EINA_TRUE; - - object->visible = EINA_TRUE; - if (!object->change) - return eina_quadtree_change(object); - - return EINA_TRUE; -} - -EAPI Eina_Inlist *eina_quadtree_collide(Eina_QuadTree * q, int x, int y, - int w, int h) -{ - Eina_Rectangle canvas; - - EINA_MAGIC_CHECK_QUADTREE(q, NULL); - - /* Now we need the tree to be up to date, so it's time */ - if (q->resize) { /* Full rebuild needed ! */ - DBG("resizing quadtree"); - q->root = - eina_quadtree_root_rebuild_pre(q, &q->change, q->root); - q->resize = EINA_FALSE; - } - - EINA_RECTANGLE_SET(&canvas, 0, 0, q->geom.w, q->geom.h); - - if (q->change) { - DBG("updating quadtree content"); - q->root = - _eina_quadtree_update(q, NULL, q->root, q->change, - EINA_FALSE, &canvas); - q->change = NULL; - q->lost = EINA_TRUE; - } - - if (q->target.x != x - || q->target.y != y || q->target.w != w || q->target.h != h) { - DBG("new target"); - EINA_RECTANGLE_SET(&q->target, x, y, w, h); - q->lost = EINA_TRUE; - } - - if (q->lost) { - DBG("computing collide"); - q->cached = _eina_quadtree_collide(NULL, q->root, - EINA_FALSE, &canvas, - &q->target); - q->lost = EINA_FALSE; - } - - return q->cached; -} - -EAPI void *eina_quadtree_object(Eina_Inlist * item) -{ - Eina_QuadTree_Item *qi; - - if (!item) - return NULL; - - qi = EINA_INLIST_CONTAINER_GET(item, Eina_QuadTree_Item); - if (!qi) - return NULL; - - EINA_MAGIC_CHECK_QUADTREE_ITEM(qi, NULL); - - if (!qi->visible) - return NULL; - - return (void *) qi->object; -} - -EAPI void eina_quadtree_resize(Eina_QuadTree * q, size_t w, size_t h) -{ - EINA_MAGIC_CHECK_QUADTREE(q); - - if (q->geom.w == w && q->geom.h == h) - return; - - q->resize = EINA_TRUE; - q->geom.w = w; - q->geom.h = h; -} - -EAPI void eina_quadtree_cycle(Eina_QuadTree * q) -{ - EINA_MAGIC_CHECK_QUADTREE(q); - - q->index = 0; -} - -EAPI void eina_quadtree_increase(Eina_QuadTree_Item * object) -{ - size_t tmp; - - tmp = object->quad->index++; - if (object->index == tmp) - return; - - object->index = tmp; - if (object->root) - object->root->sorted = EINA_FALSE; -} - -Eina_Bool eina_quadtree_init(void) -{ - _eina_log_qd_dom = eina_log_domain_register("eina_quadtree", - EINA_LOG_COLOR_DEFAULT); - if (_eina_log_qd_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_quadtree"); - return EINA_FALSE; - } -#define EMS(n) eina_magic_string_static_set(n, n ## _STR) - EMS(EINA_MAGIC_QUADTREE); - EMS(EINA_MAGIC_QUADTREE_ROOT); - EMS(EINA_MAGIC_QUADTREE_ITEM); -#undef EMS - - items_mp = - eina_mempool_add("chained_mempool", "QuadTree Item", NULL, - sizeof(Eina_QuadTree_Item), 320); - root_mp = - eina_mempool_add("chained_mempool", "QuadTree Root", NULL, - sizeof(Eina_QuadTree_Root), 32); - - return EINA_TRUE; -} - -Eina_Bool eina_quadtree_shutdown(void) -{ - eina_log_domain_unregister(_eina_log_qd_dom); - _eina_log_qd_dom = -1; - return EINA_TRUE; -} diff --git a/tests/suite/ecore/src/lib/eina_rbtree.c b/tests/suite/ecore/src/lib/eina_rbtree.c deleted file mode 100644 index 543d45ab17..0000000000 --- a/tests/suite/ecore/src/lib/eina_rbtree.c +++ /dev/null @@ -1,615 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_array.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_rbtree.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -#define EINA_RBTREE_ITERATOR_PREFIX_MASK 0x1 -#define EINA_RBTREE_ITERATOR_INFIX_MASK 0x2 -#define EINA_RBTREE_ITERATOR_POSTFIX_MASK 0x4 - -typedef struct _Eina_Iterator_Rbtree Eina_Iterator_Rbtree; -typedef struct _Eina_Iterator_Rbtree_List Eina_Iterator_Rbtree_List; - -struct _Eina_Iterator_Rbtree { - Eina_Iterator iterator; - - Eina_Array *stack; - - unsigned char mask; -}; - -struct _Eina_Iterator_Rbtree_List { - Eina_Rbtree *tree; - - Eina_Rbtree_Direction dir:1; - Eina_Bool up:1; -}; - -static Eina_Iterator_Rbtree_List *_eina_rbtree_iterator_list_new(const - Eina_Rbtree - * tree) -{ - Eina_Iterator_Rbtree_List *new; - - eina_error_set(0); - new = malloc(sizeof(Eina_Iterator_Rbtree_List)); - if (!new) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - new->tree = (Eina_Rbtree *) tree; - new->dir = EINA_RBTREE_RIGHT; - new->up = EINA_FALSE; - - return new; -} - -static Eina_Rbtree *_eina_rbtree_iterator_get_content(Eina_Iterator_Rbtree - * it) -{ - if (eina_array_count_get(it->stack) <= 0) - return NULL; - - return eina_array_data_get(it->stack, 0); -} - -static void _eina_rbtree_iterator_free(Eina_Iterator_Rbtree * it) -{ - Eina_Iterator_Rbtree_List *item; - Eina_Array_Iterator et; - unsigned int i; - - EINA_ARRAY_ITER_NEXT(it->stack, i, item, et) - free(item); - - eina_array_free(it->stack); - free(it); -} - -static Eina_Bool -_eina_rbtree_iterator_next(Eina_Iterator_Rbtree * it, void **data) -{ - Eina_Iterator_Rbtree_List *last; - Eina_Iterator_Rbtree_List *new; - Eina_Rbtree *tree; - - if (eina_array_count_get(it->stack) <= 0) - return EINA_FALSE; - - last = - eina_array_data_get(it->stack, - eina_array_count_get(it->stack) - 1); - tree = last->tree; - - if (!last->tree || last->up == EINA_TRUE) { - last = eina_array_pop(it->stack); - while (last->dir == EINA_RBTREE_LEFT || !last->tree) { - if (tree) - if ((it-> - mask & - EINA_RBTREE_ITERATOR_POSTFIX_MASK) == - EINA_RBTREE_ITERATOR_POSTFIX_MASK) { - free(last); - - if (eina_array_count_get(it->stack) - > 0) { - last = - eina_array_data_get - (it->stack, - eina_array_count_get - (it->stack) - - 1); - last->up = EINA_TRUE; - } - - goto onfix; - } - - free(last); - - last = eina_array_pop(it->stack); - if (!last) - return EINA_FALSE; - - tree = last->tree; - } - - last->dir = EINA_RBTREE_LEFT; - last->up = EINA_FALSE; - - eina_array_push(it->stack, last); - - if ((it->mask & EINA_RBTREE_ITERATOR_INFIX_MASK) == - EINA_RBTREE_ITERATOR_INFIX_MASK) - goto onfix; - } - - new = _eina_rbtree_iterator_list_new(last->tree->son[last->dir]); - if (!new) - return EINA_FALSE; - - eina_array_push(it->stack, new); - - if (last->dir == EINA_RBTREE_RIGHT) - if ((it->mask & EINA_RBTREE_ITERATOR_PREFIX_MASK) == - EINA_RBTREE_ITERATOR_PREFIX_MASK) - goto onfix; - - return _eina_rbtree_iterator_next(it, data); - - onfix: - *data = tree; - return EINA_TRUE; -} - -static Eina_Iterator *_eina_rbtree_iterator_build(const Eina_Rbtree * root, - unsigned char mask) -{ - Eina_Iterator_Rbtree_List *first; - Eina_Iterator_Rbtree *it; - - eina_error_set(0); - it = calloc(1, sizeof(Eina_Iterator_Rbtree)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - it->stack = eina_array_new(8); - if (!it->stack) - goto on_error2; - - first = _eina_rbtree_iterator_list_new(root); - if (!first) - goto on_error; - - eina_array_push(it->stack, first); - - it->mask = mask; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_eina_rbtree_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(_eina_rbtree_iterator_get_content); - it->iterator.free = FUNC_ITERATOR_FREE(_eina_rbtree_iterator_free); - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - return &it->iterator; - - on_error: - eina_array_free(it->stack); - on_error2: - free(it); - - return NULL; -} - -/* - * Thanks to Julienne Walker public domain tutorial. - * http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx - */ - -static void _eina_rbtree_node_init(Eina_Rbtree * node) -{ - if (!node) - return; - - node->son[0] = NULL; - node->son[1] = NULL; - - node->color = EINA_RBTREE_RED; -} - -static inline Eina_Bool _eina_rbtree_is_red(Eina_Rbtree * node) -{ - return ! !node && node->color == EINA_RBTREE_RED; -} - -static inline Eina_Rbtree *_eina_rbtree_inline_single_rotation(Eina_Rbtree - * node, - Eina_Rbtree_Direction - dir) -{ - Eina_Rbtree *save = node->son[!dir]; - - node->son[!dir] = save->son[dir]; - save->son[dir] = node; - - node->color = EINA_RBTREE_RED; - save->color = EINA_RBTREE_BLACK; - - return save; -} - -static inline Eina_Rbtree *_eina_rbtree_inline_double_rotation(Eina_Rbtree - * node, - Eina_Rbtree_Direction - dir) -{ - node->son[!dir] = - _eina_rbtree_inline_single_rotation(node->son[!dir], !dir); - return _eina_rbtree_inline_single_rotation(node, dir); -} - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Rbtree_Group Red-Black tree - * - * @brief These functions provide Red-Black trees management. - * - * @{ - */ - -EAPI Eina_Rbtree *eina_rbtree_inline_insert(Eina_Rbtree * root, - Eina_Rbtree * node, - Eina_Rbtree_Cmp_Node_Cb cmp, - const void *data) -{ - Eina_Rbtree head; - Eina_Rbtree *g, *t; /* Grandparent & parent */ - Eina_Rbtree *p, *q; /* Iterator & parent */ - /* WARNING: - Compiler is not able to understand the underlying algorithm and don't know that - first top node is always black, so it will never use last before running the loop - one time. - */ - Eina_Rbtree_Direction dir, last; - - EINA_SAFETY_ON_NULL_RETURN_VAL(node, root); - EINA_SAFETY_ON_NULL_RETURN_VAL(cmp, root); - - if (!node) - return root; - - _eina_rbtree_node_init(node); - - if (!root) { - root = node; - goto end_add; - } - - memset(&head, 0, sizeof(Eina_Rbtree)); - last = dir = EINA_RBTREE_LEFT; - - /* Set up helpers */ - t = &head; - g = p = NULL; - q = t->son[1] = root; - - /* Search down the tree */ - for (;;) { - if (!q) - /* Insert new node at the bottom */ - p->son[dir] = q = node; - else if (_eina_rbtree_is_red(q->son[0]) - && _eina_rbtree_is_red(q->son[1])) { - /* Color flip */ - q->color = EINA_RBTREE_RED; - q->son[0]->color = EINA_RBTREE_BLACK; - q->son[1]->color = EINA_RBTREE_BLACK; - } - - /* Fix red violation */ - if (_eina_rbtree_is_red(q) && _eina_rbtree_is_red(p)) { - Eina_Rbtree_Direction dir2; - - dir2 = - (t->son[1] == - g) ? EINA_RBTREE_RIGHT : EINA_RBTREE_LEFT; - - if (q == p->son[last]) - t->son[dir2] = - _eina_rbtree_inline_single_rotation(g, - !last); - else - t->son[dir2] = - _eina_rbtree_inline_double_rotation(g, - !last); - } - - /* Stop if found */ - if (q == node) - break; - - last = dir; - dir = cmp(q, node, (void *) data); - - /* Update helpers */ - if (g) - t = g; - - g = p, p = q; - q = q->son[dir]; - } - - root = head.son[1]; - - end_add: - /* Make root black */ - root->color = EINA_RBTREE_BLACK; - - return root; -} - -EAPI Eina_Rbtree *eina_rbtree_inline_remove(Eina_Rbtree * root, - Eina_Rbtree * node, - Eina_Rbtree_Cmp_Node_Cb cmp, - const void *data) -{ - Eina_Rbtree head; - Eina_Rbtree *q, *p; - Eina_Rbtree *f = NULL; - Eina_Rbtree_Direction dir; - - EINA_SAFETY_ON_NULL_RETURN_VAL(node, root); - EINA_SAFETY_ON_NULL_RETURN_VAL(cmp, root); - - if (!root || !node) - return root; - - memset(&head, 0, sizeof(Eina_Rbtree)); - - dir = EINA_RBTREE_RIGHT; - q = &head; - p = NULL; - q->son[EINA_RBTREE_RIGHT] = root; - - /* Search and push a red down */ - while (q->son[dir]) { - Eina_Rbtree_Direction last = dir; - Eina_Rbtree *g; - - /* Update helpers */ - g = p; - p = q; - q = q->son[dir]; - dir = cmp(q, node, (void *) data); - - /* Save parent node found */ - if (q == node) - f = p; - - /* Push the red node down */ - if (!_eina_rbtree_is_red(q) - && !_eina_rbtree_is_red(q->son[dir])) { - if (_eina_rbtree_is_red(q->son[!dir])) - q = p->son[last] = - _eina_rbtree_inline_single_rotation(q, - dir); - else if (!_eina_rbtree_is_red(q->son[!dir])) { - Eina_Rbtree *s = p->son[!last]; - - if (s) { - if (!_eina_rbtree_is_red - (s->son[EINA_RBTREE_LEFT]) - && !_eina_rbtree_is_red(s-> - son - [EINA_RBTREE_RIGHT])) - { -/* Color flip */ - p->color = - EINA_RBTREE_BLACK; - p->son[EINA_RBTREE_LEFT]-> - color = - EINA_RBTREE_RED; - p->son[EINA_RBTREE_RIGHT]-> - color = - EINA_RBTREE_RED; - } else { - Eina_Rbtree_Direction dir2; - - dir2 = g->son[1] == - p ? EINA_RBTREE_RIGHT : - EINA_RBTREE_LEFT; - - if (_eina_rbtree_is_red - (s->son[last])) { - g->son[dir2] = - _eina_rbtree_inline_double_rotation - (p, last); - if (f == g) { - p = g-> - son - [dir2]-> - son - [last]; - f = g-> - son - [dir2]; - } - } else - if (_eina_rbtree_is_red - (s->son[!last])) { - g->son[dir2] = - _eina_rbtree_inline_single_rotation - (p, last); - if (f == g) { - p = g-> - son - [dir2]-> - son - [last]; - f = g-> - son - [dir2]; - } - } - -/* Ensure correct coloring */ - q->color = - g->son[dir2]->color = - EINA_RBTREE_RED; - g->son[dir2]-> - son[EINA_RBTREE_LEFT]-> - color = - EINA_RBTREE_BLACK; - g->son[dir2]-> - son - [EINA_RBTREE_RIGHT]-> - color = - EINA_RBTREE_BLACK; - } - } - } - } - } - - /* Replace and remove if found */ - if (f) { - /* 'q' should take the place of 'node' parent */ - f->son[f->son[1] == node] = q; - - /* Switch the link from the parent to q's son */ - p->son[p->son[1] == q] = q->son[!q->son[0]]; - - /* Put q at the place of node */ - q->son[0] = node->son[0]; - q->son[1] = node->son[1]; - q->color = node->color; - - /* Reset node link */ - node->son[0] = NULL; - node->son[1] = NULL; - } - - root = head.son[1]; - if (root) - root->color = EINA_RBTREE_BLACK; - - return root; -} - -/** - * @brief Returned a new prefix iterator associated to a rbtree. - * - * @param root The root of rbtree. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * root. It will iterate the tree using prefix walk. If @p root is @c - * NULL, this function still returns a valid iterator that will always - * return false on eina_iterator_next(), thus keeping API sane. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the rbtree structure changes then the iterator becomes - * invalid! That is, if you add or remove nodes this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_rbtree_iterator_prefix(const Eina_Rbtree * root) -{ - return _eina_rbtree_iterator_build(root, - EINA_RBTREE_ITERATOR_PREFIX_MASK); -} - -/** - * @brief Returned a new prefix iterator associated to a rbtree. - * - * @param root The root of rbtree. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * root. It will iterate the tree using infix walk. If @p root is @c - * NULL, this function still returns a valid iterator that will always - * return false on eina_iterator_next(), thus keeping API sane. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the rbtree structure changes then the iterator becomes - * invalid! That is, if you add or remove nodes this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_rbtree_iterator_infix(const Eina_Rbtree * root) -{ - return _eina_rbtree_iterator_build(root, - EINA_RBTREE_ITERATOR_INFIX_MASK); -} - -/** - * @brief Returned a new prefix iterator associated to a rbtree. - * - * @param root The root of rbtree. - * @return A new iterator. - * - * This function returns a newly allocated iterator associated to @p - * root. It will iterate the tree using postfix walk. If @p root is @c - * NULL, this function still returns a valid iterator that will always - * return false on eina_iterator_next(), thus keeping API sane. - * - * If the memory can not be allocated, NULL is returned and - * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is - * returned. - * - * @warning if the rbtree structure changes then the iterator becomes - * invalid! That is, if you add or remove nodes this iterator - * behavior is undefined and your program may crash! - */ -EAPI Eina_Iterator *eina_rbtree_iterator_postfix(const Eina_Rbtree * root) -{ - return _eina_rbtree_iterator_build(root, - EINA_RBTREE_ITERATOR_POSTFIX_MASK); -} - -EAPI void -eina_rbtree_delete(Eina_Rbtree * root, Eina_Rbtree_Free_Cb func, - void *data) -{ - if (!root) - return; - - EINA_SAFETY_ON_NULL_RETURN(func); - - eina_rbtree_delete(root->son[0], func, data); - eina_rbtree_delete(root->son[1], func, data); - func(root, data); -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_rectangle.c b/tests/suite/ecore/src/lib/eina_rectangle.c deleted file mode 100644 index dee79ff374..0000000000 --- a/tests/suite/ecore/src/lib/eina_rectangle.c +++ /dev/null @@ -1,661 +0,0 @@ -/* 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <stdlib.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_magic.h" -#include "eina_inlist.h" -#include "eina_mempool.h" -#include "eina_list.h" -#include "eina_trash.h" -#include "eina_log.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_rectangle.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -#define EINA_RECTANGLE_POOL_MAGIC 0x1578FCB0 -#define EINA_RECTANGLE_ALLOC_MAGIC 0x1578FCB1 - -#define BUCKET_THRESHOLD 110 - -typedef struct _Eina_Rectangle_Alloc Eina_Rectangle_Alloc; - -struct _Eina_Rectangle_Pool { - Eina_Inlist *head; - Eina_List *empty; - void *data; - - Eina_Trash *bucket; - unsigned int bucket_count; - - unsigned int references; - int w; - int h; - - Eina_Bool sorted; - EINA_MAGIC}; - -struct _Eina_Rectangle_Alloc { - EINA_INLIST; - Eina_Rectangle_Pool *pool; - EINA_MAGIC}; - -#define EINA_MAGIC_CHECK_RECTANGLE_POOL(d) \ - do { \ - if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_POOL_MAGIC)) { \ - EINA_MAGIC_FAIL((d), EINA_RECTANGLE_POOL_MAGIC); } \ - } while (0) - -#define EINA_MAGIC_CHECK_RECTANGLE_ALLOC(d) \ - do { \ - if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_ALLOC_MAGIC)) { \ - EINA_MAGIC_FAIL((d), EINA_RECTANGLE_ALLOC_MAGIC); } \ - } while (0) - -static Eina_Mempool *_eina_rectangle_alloc_mp = NULL; -static Eina_Mempool *_eina_rectangle_mp = NULL; - -static Eina_Trash *_eina_rectangles = NULL; -static unsigned int _eina_rectangles_count = 0; -static int _eina_rectangle_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_rectangle_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__) - -static int -_eina_rectangle_cmp(const Eina_Rectangle * r1, const Eina_Rectangle * r2) -{ - return (r2->w * r2->h) - (r1->w * r1->h); -} - -static Eina_List *_eina_rectangle_merge_list(Eina_List * empty, - Eina_Rectangle * r) -{ - Eina_Rectangle *match; - Eina_List *l; - int xw; - int yh; - - if (r->w == 0 || r->h == 0) { - eina_rectangle_free(r); - return empty; - } - - start_again: - xw = r->x + r->w; - yh = r->y + r->h; - - EINA_LIST_FOREACH(empty, l, match) { - if (match->x == r->x && match->w == r->w - && (match->y == yh || r->y == match->y + match->h)) { - if (match->y > r->y) - match->y = r->y; - - match->h += r->h; - - eina_rectangle_free(r); - - empty = eina_list_remove_list(empty, l); - - r = match; - - goto start_again; - } else if (match->y == r->y && match->h == r->h - && (match->x == xw - || r->x == match->x + match->w)) { - if (match->x > r->x) - match->x = r->x; - - match->w += r->w; - - eina_rectangle_free(r); - - empty = eina_list_remove_list(empty, l); - - r = match; - - goto start_again; - } - } - - return eina_list_append(empty, r); -} - -static Eina_List *_eina_rectangle_empty_space_find(Eina_List * empty, - int w, int h, int *x, - int *y) -{ - Eina_Rectangle *r; - Eina_List *l; - - EINA_LIST_FOREACH(empty, l, r) { - if (r->w >= w && r->h >= h) { - /* Remove l from empty */ - empty = eina_list_remove_list(empty, l); - /* Remember x and y */ - *x = r->x; - *y = r->y; - /* Split r in 2 rectangle if needed (only the empty one) and insert them */ - if (r->w == w) { - r->y += h; - r->h -= h; - } else if (r->h == h) { - r->x += w; - r->w -= w; - } else { - int rx1, ry1, rw1, rh1; - int x2, y2, w2, h2; - - rx1 = r->x + w; - ry1 = r->y; - rw1 = r->w - w; - /* h1 could be h or r->h */ - x2 = r->x; - y2 = r->y + h; - /* w2 could be w or r->w */ - h2 = r->h - h; - - if (rw1 * r->h > h2 * r->w) { - rh1 = r->h; - w2 = w; - } else { - rh1 = h; - w2 = r->w; - } - - EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1); - empty = - _eina_rectangle_merge_list(empty, r); - - r = eina_rectangle_new(x2, y2, w2, h2); - } - - if (r) { - empty = _eina_rectangle_merge_list(empty, r); /* Return empty */ - - } - - return empty; - } - } - - *x = -1; - *y = -1; - return empty; -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -Eina_Bool eina_rectangle_init(void) -{ - const char *choice, *tmp; - - _eina_rectangle_log_dom = - eina_log_domain_register("eina_rectangle", - EINA_LOG_COLOR_DEFAULT); - if (_eina_rectangle_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_rectangle"); - return EINA_FALSE; - } -#ifdef EINA_DEFAULT_MEMPOOL - choice = "pass_through"; -#else - choice = "chained_mempool"; -#endif - tmp = getenv("EINA_MEMPOOL"); - if (tmp && tmp[0]) - choice = tmp; - - _eina_rectangle_alloc_mp = eina_mempool_add - (choice, "rectangle-alloc", NULL, - sizeof(Eina_Rectangle_Alloc) + sizeof(Eina_Rectangle), 1024); - if (!_eina_rectangle_alloc_mp) { - ERR("Mempool for rectangle cannot be allocated in rectangle init."); - goto init_error; - } - - _eina_rectangle_mp = eina_mempool_add - (choice, "rectangle", NULL, sizeof(Eina_Rectangle), 256); - if (!_eina_rectangle_mp) { - ERR("Mempool for rectangle cannot be allocated in rectangle init."); - goto init_error; - } - - return EINA_TRUE; - - init_error: - eina_log_domain_unregister(_eina_rectangle_log_dom); - _eina_rectangle_log_dom = -1; - - return EINA_FALSE; -} - -Eina_Bool eina_rectangle_shutdown(void) -{ - Eina_Rectangle *del; - - while ((del = eina_trash_pop(&_eina_rectangles))) - eina_mempool_free(_eina_rectangle_mp, del); - _eina_rectangles_count = 0; - - eina_mempool_del(_eina_rectangle_alloc_mp); - eina_mempool_del(_eina_rectangle_mp); - - eina_log_domain_unregister(_eina_rectangle_log_dom); - _eina_rectangle_log_dom = -1; - - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Rectangle_Group Rectangle - * - * @brief These functions provide rectangle management. - * - * @{ - */ - -/** - * @brief Create a new rectangle. - * - * @param x The X coordinate of the top left corner of the rectangle. - * @param y The Y coordinate of the top left corner of the rectangle. - * @param w The width of the rectangle. - * @param h The height of the rectangle. - * @return The new rectangle on success, @ NULL otherwise. - * - * This function creates a rectangle which top left corner has the - * coordinates (@p x, @p y), with height @p w and height @p h and adds - * it to the rectangles pool. No check is done on @p w and @p h. This - * function returns a new rectangle on success, @c NULL otherwhise. - */ -EAPI Eina_Rectangle *eina_rectangle_new(int x, int y, int w, int h) -{ - Eina_Rectangle *rect; - - if (_eina_rectangles) { - rect = eina_trash_pop(&_eina_rectangles); - _eina_rectangles_count--; - } else - rect = - eina_mempool_malloc(_eina_rectangle_mp, - sizeof(Eina_Rectangle)); - - if (!rect) - return NULL; - - EINA_RECTANGLE_SET(rect, x, y, w, h); - - return rect; -} - -/** - * @brief Free the given rectangle. - * - * @param rect The rectangle to free. - * - * This function removes @p rect from the rectangles pool. - */ -EAPI void eina_rectangle_free(Eina_Rectangle * rect) -{ - EINA_SAFETY_ON_NULL_RETURN(rect); - - if (_eina_rectangles_count > BUCKET_THRESHOLD) - eina_mempool_free(_eina_rectangle_mp, rect); - else { - eina_trash_push(&_eina_rectangles, rect); - _eina_rectangles_count++; - } -} - -/** - * @brief Add a rectangle in a new pool. - * - * @param w The width of the rectangle. - * @param h The height of the rectangle. - * @return A newly allocated pool on success, @c NULL otherwise. - * - * This function adds the rectangle of size (@p width, @p height) to a - * new pool. If the pool can not be created, @c NULL is - * returned. Otherwise the newly allocated pool is returned. - */ -EAPI Eina_Rectangle_Pool *eina_rectangle_pool_new(int w, int h) -{ - Eina_Rectangle_Pool *new; - - new = malloc(sizeof(Eina_Rectangle_Pool)); - if (!new) - return NULL; - - new->head = NULL; - new->empty = - eina_list_append(NULL, eina_rectangle_new(0, 0, w, h)); - new->references = 0; - new->sorted = EINA_FALSE; - new->w = w; - new->h = h; - new->bucket = NULL; - new->bucket_count = 0; - - EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC); - DBG("pool=%p, size=(%d, %d)", new, w, h); - - return new; -} - -/** - * @brief Free the given pool. - * - * @param pool The pool to free. - * - * This function frees the allocated data of @p pool. If @p pool is - * @c NULL, ths function returned immediately. - */ -EAPI void eina_rectangle_pool_free(Eina_Rectangle_Pool * pool) -{ - Eina_Rectangle_Alloc *del; - - EINA_SAFETY_ON_NULL_RETURN(pool); - DBG("pool=%p, size=(%d, %d), references=%u", - pool, pool->w, pool->h, pool->references); - while (pool->head) { - del = (Eina_Rectangle_Alloc *) pool->head; - - pool->head = (EINA_INLIST_GET(del))->next; - - EINA_MAGIC_SET(del, EINA_MAGIC_NONE); - eina_mempool_free(_eina_rectangle_alloc_mp, del); - } - - while (pool->bucket) { - del = eina_trash_pop(&pool->bucket); - eina_mempool_free(_eina_rectangle_alloc_mp, del); - } - - MAGIC_FREE(pool); -} - -/** - * @brief Return the number of rectangles in the given pool. - * - * @param pool The pool. - * @return The number of rectangles in the pool. - * - * This function returns the number of rectangles in @p pool. - */ -EAPI int eina_rectangle_pool_count(Eina_Rectangle_Pool * pool) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(pool, 0); - return pool->references; -} - -/** - * @brief Request a rectangle of given size in the given pool. - * - * @param pool The pool. - * @param w The width of the rectangle to request. - * @param h The height of the rectangle to request. - * @return The requested rectangle on success, @c NULL otherwise. - * - * This function retrieve from @p pool the rectangle of width @p w and - * height @p h. If @p pool is @c NULL, or @p w or @p h are non-positive, - * the function returns @c NULL. If @p w or @p h are greater than the - * pool size, the function returns @c NULL. On success, the function - * returns the rectangle which matches the size (@p w, @p h). - * Otherwise it returns @c NULL. - */ -EAPI Eina_Rectangle *eina_rectangle_pool_request(Eina_Rectangle_Pool * - pool, int w, int h) -{ - Eina_Rectangle_Alloc *new; - Eina_Rectangle *rect; - int x; - int y; - - EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL); - - DBG("pool=%p, size=(%d, %d), references=%u", - pool, pool->w, pool->h, pool->references); - - if (w <= 0 || h <= 0) - return NULL; - - if (w > pool->w || h > pool->h) - return NULL; - - /* Sort empty if dirty */ - if (pool->sorted) { - pool->empty = - eina_list_sort(pool->empty, 0, - EINA_COMPARE_CB(_eina_rectangle_cmp)); - pool->sorted = EINA_TRUE; - } - - pool->empty = - _eina_rectangle_empty_space_find(pool->empty, w, h, &x, &y); - if (x == -1) - return NULL; - - pool->sorted = EINA_FALSE; - - if (pool->bucket_count > 0) { - new = eina_trash_pop(&pool->bucket); - pool->bucket_count--; - } else - new = eina_mempool_malloc(_eina_rectangle_alloc_mp, - sizeof(Eina_Rectangle_Alloc) + - sizeof(Eina_Rectangle)); - - if (!new) - return NULL; - - rect = (Eina_Rectangle *) (new + 1); - eina_rectangle_coords_from(rect, x, y, w, h); - - pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new)); - pool->references++; - - new->pool = pool; - - EINA_MAGIC_SET(new, EINA_RECTANGLE_ALLOC_MAGIC); - DBG("rect=%p pool=%p, size=(%d, %d), references=%u", - rect, pool, pool->w, pool->h, pool->references); - - return rect; -} - -/** - * @brief Remove the given rectangle from the pool. - * - * @param rect The rectangle to remove from the pool. - * - * This function removes @p rect from the pool. If @p rect is - * @c NULL, the function returns immediately. Otherwise it remoes @p - * rect from the pool. - */ -EAPI void eina_rectangle_pool_release(Eina_Rectangle * rect) -{ - Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *) rect) - 1; - Eina_Rectangle *r; - - EINA_SAFETY_ON_NULL_RETURN(rect); - - EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era); - EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool); - - DBG("rect=%p pool=%p, size=(%d, %d), references=%u", - rect, era->pool, era->pool->w, era->pool->h, - era->pool->references); - - era->pool->references--; - era->pool->head = - eina_inlist_remove(era->pool->head, EINA_INLIST_GET(era)); - - r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h); - if (r) { - era->pool->empty = - _eina_rectangle_merge_list(era->pool->empty, r); - era->pool->sorted = EINA_FALSE; - } - - if (era->pool->bucket_count < BUCKET_THRESHOLD) { - Eina_Rectangle_Pool *pool; - - pool = era->pool; - - pool->bucket_count++; - eina_trash_push(&pool->bucket, era); - } else { - EINA_MAGIC_SET(era, EINA_MAGIC_NONE); - eina_mempool_free(_eina_rectangle_alloc_mp, era); - } -} - -/** - * @brief Return the pool of the given rectangle. - * - * @param rect The rectangle. - * @return The pool of the given rectangle. - * - * This function returns the pool in which @p rect is. If @p rect is - * @c NULL, @c NULL is returned. - */ -EAPI Eina_Rectangle_Pool *eina_rectangle_pool_get(Eina_Rectangle * rect) -{ - Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *) rect) - 1; - - EINA_SAFETY_ON_NULL_RETURN_VAL(rect, NULL); - - EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era); - EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool); - - return era->pool; -} - -/** - * @brief Set the data to the given pool. - * - * @param pool The pool. - * @param data The data to set. - * - * This function sets @p data to @p pool. If @p pool is @c NULL, this - * function does nothing. - */ -EAPI void -eina_rectangle_pool_data_set(Eina_Rectangle_Pool * pool, const void *data) -{ - EINA_MAGIC_CHECK_RECTANGLE_POOL(pool); - EINA_SAFETY_ON_NULL_RETURN(pool); - - DBG("data=%p pool=%p, size=(%d, %d), references=%u", - data, pool, pool->w, pool->h, pool->references); - - pool->data = (void *) data; -} - -/** - * @brief Get the data from the given pool. - * - * @param pool The pool. - * @return The returned data. - * - * This function gets the data from @p pool set by - * eina_rectangle_pool_data_set(). If @p pool is @c NULL, this - * function returns @c NULL. - */ -EAPI void *eina_rectangle_pool_data_get(Eina_Rectangle_Pool * pool) -{ - EINA_MAGIC_CHECK_RECTANGLE_POOL(pool); - EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL); - - return pool->data; -} - -/** - * @brief Return the width and height of the given pool. - * - * @param pool The pool. - * @param w The returned width. - * @param h The returned height. - * @return #EINA_TRUE on success, #EINA_FALSE otherwise. - * - * This function returns the width and height of @p pool and store - * them in respectively @p w and @p h if they are not @c NULL. If - * @p pool is @c NULL, #EINA_FALSE is returned. Otherwise #EINA_TRUE is - * returned. - */ -EAPI Eina_Bool -eina_rectangle_pool_geometry_get(Eina_Rectangle_Pool * pool, int *w, - int *h) -{ - if (!pool) - return EINA_FALSE; - - EINA_MAGIC_CHECK_RECTANGLE_POOL(pool); - EINA_SAFETY_ON_NULL_RETURN_VAL(pool, EINA_FALSE); - - if (w) - *w = pool->w; - - if (h) - *h = pool->h; - - return EINA_TRUE; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_safety_checks.c b/tests/suite/ecore/src/lib/eina_safety_checks.c deleted file mode 100644 index ba4fc3da2f..0000000000 --- a/tests/suite/ecore/src/lib/eina_safety_checks.c +++ /dev/null @@ -1,112 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2008 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "eina_private.h" -#include "eina_error.h" -#include "eina_log.h" -#include "eina_safety_checks.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Shut down the safety checks module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the error module set up by - * eina_safety_checks_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_safety_checks_shutdown(void) -{ - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Safety_Checks_Group Safety Checks - * - * Safety checks are a set of macros to check for parameters or values - * that should never happen, it is similar in concept to assert(), but - * will log and return instead of abort() your program. - * - * Since these cases should never happen, one may wantto keep safety - * checks enabled during tests but disable then during deploy, not - * doing any checks at all. This is a common requirement for embedded - * systems. Whenever to check or not should be set during compile time - * by using @c --disable-safety-checks or @c --enable-safety-checks - * options to @c configure script. - * - * Whenever these macros capture an error, EINA_LOG_ERR() will be - * called and @c eina_error set to @c EINA_ERROR_SAFETY_FAILED and can - * be checked with eina_error_get() after call. - * - * @see EINA_SAFETY_ON_NULL_RETURN(), EINA_SAFETY_ON_NULL_RETURN_VAL() - * and other macros. - * - * @{ - */ - -/** - * @cond LOCAL - */ - -EAPI Eina_Error EINA_ERROR_SAFETY_FAILED = 0; - -static const char EINA_ERROR_SAFETY_FAILED_STR[] = "Safety check failed."; - -/** - * @endcond - */ - -/** - * @internal - * @brief Initialize the safety checks module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the safety checks module of Eina. It is - * called by eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_safety_checks_init(void) -{ - EINA_ERROR_SAFETY_FAILED = - eina_error_msg_static_register(EINA_ERROR_SAFETY_FAILED_STR); - return EINA_TRUE; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_sched.c b/tests/suite/ecore/src/lib/eina_sched.c deleted file mode 100644 index fc32319bfa..0000000000 --- a/tests/suite/ecore/src/lib/eina_sched.c +++ /dev/null @@ -1,90 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2010 ProFUSION embedded systems - * - * 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 <https://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef EFL_HAVE_POSIX_THREADS -#include <pthread.h> -#ifdef __linux__ -#include <sched.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <errno.h> -#endif -#endif - -#include "eina_sched.h" -#include "eina_log.h" - -#define RTNICENESS 5 -#define NICENESS 5 - -/** - * @brief Lower priority of current thread. - * - * It's used by worker threads so they use up background cpu and do not stall - * the main thread If current thread is running with real-time priority, we - * decrease our priority by @c RTNICENESS. This is done in a portable way. - * - * Otherwise (we are running with SCHED_OTHER policy) there's no portable way to - * set the nice level on current thread. In Linux, it does work and it's the - * only one that is implemented as of now. In this case the nice level is - * incremented on this thread by @c NICENESS. - */ -EAPI void eina_sched_prio_drop(void) -{ -#ifdef EFL_HAVE_POSIX_THREADS - struct sched_param param; - int pol, prio, ret; - pthread_t pthread_id; - - pthread_id = pthread_self(); - ret = pthread_getschedparam(pthread_id, &pol, ¶m); - if (ret) { - EINA_LOG_ERR("Unable to query sched parameters"); - return; - } - - if (EINA_UNLIKELY(pol == SCHED_RR || pol == SCHED_FIFO)) { - prio = sched_get_priority_max(pol); - param.sched_priority += RTNICENESS; - if (prio > 0 && param.sched_priority > prio) - param.sched_priority = prio; - - pthread_setschedparam(pthread_id, pol, ¶m); - } -#ifdef __linux__ - else { - errno = 0; - prio = getpriority(PRIO_PROCESS, 0); - if (errno == 0) { - prio += NICENESS; - if (prio > 19) - prio = 19; - - setpriority(PRIO_PROCESS, 0, prio); - } - } -#endif -#else - EINA_LOG_ERR("Eina does not have support for threads enabled" - "or it doesn't support setting scheduler priorities"); -#endif -} diff --git a/tests/suite/ecore/src/lib/eina_share_common.c b/tests/suite/ecore/src/lib/eina_share_common.c deleted file mode 100644 index 61def98561..0000000000 --- a/tests/suite/ecore/src/lib/eina_share_common.c +++ /dev/null @@ -1,954 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2010 - * Carsten Haitzler, - * Jorge Luis Zapata Muga, - * Cedric Bail, - * Gustavo Sverzut Barbieri - * Tom Hacohen - * 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 <https://www.gnu.org/licenses/>. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (C) 2008 Peter Wehrfritz - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies of the Software and its Copyright notices. In addition publicly - * documented acknowledgment must be given that this software has been used if no - * source code of this software is made available publicly. This includes - * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing - * documents or any documentation provided with any product containing this - * software. This License does not apply to any software that links to the - * libraries provided by this software (statically or dynamically), but only to - * the software provided. - * - * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice - * and it's intent. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stddef.h> - -#ifdef EFL_HAVE_POSIX_THREADS -#include <pthread.h> -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_hash.h" -#include "eina_rbtree.h" -#include "eina_error.h" -#include "eina_log.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_share_common.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -#define EINA_SHARE_COMMON_BUCKETS 256 -#define EINA_SHARE_COMMON_MASK 0xFF - -static const char EINA_MAGIC_SHARE_STR[] = "Eina Share"; -static const char EINA_MAGIC_SHARE_HEAD_STR[] = "Eina Share Head"; - - -#define EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(d, unlock, ...) \ - do { \ - if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_SHARE_HEAD)) \ - { \ - EINA_MAGIC_FAIL((d), EINA_MAGIC_SHARE_HEAD); \ - unlock; \ - return __VA_ARGS__; \ - } \ - } while (0) - -#define EINA_MAGIC_CHECK_SHARE_COMMON_NODE(d, _node_magic, unlock) \ - do { \ - if (!EINA_MAGIC_CHECK((d), _node_magic)) \ - { \ - unlock; \ - EINA_MAGIC_FAIL((d), _node_magic); \ - } \ - } while (0) - -#ifdef EINA_SHARE_USAGE -typedef struct _Eina_Share_Common_Population Eina_Share_Common_Population; -#endif - -typedef struct _Eina_Share_Common Eina_Share_Common; -typedef struct _Eina_Share_Common_Node Eina_Share_Common_Node; -typedef struct _Eina_Share_Common_Head Eina_Share_Common_Head; - -int _eina_share_common_log_dom = -1; - -struct _Eina_Share { - Eina_Share_Common *share; - Eina_Magic node_magic; -#ifdef EINA_SHARE_COMMON_USAGE - Eina_Share_Common_Population population; - int max_node_population; -#endif -}; - -struct _Eina_Share_Common { - Eina_Share_Common_Head *buckets[EINA_SHARE_COMMON_BUCKETS]; - - EINA_MAGIC}; - -struct _Eina_Share_Common_Node { - Eina_Share_Common_Node *next; - - EINA_MAGIC unsigned int length; - unsigned int references; - char str[]; -}; - -struct _Eina_Share_Common_Head { - EINA_RBTREE; - EINA_MAGIC int hash; - -#ifdef EINA_SHARE_COMMON_USAGE - int population; -#endif - - Eina_Share_Common_Node *head; - Eina_Share_Common_Node builtin_node; -}; - -#ifdef EFL_HAVE_THREADS -Eina_Bool _share_common_threads_activated = EINA_FALSE; - -#ifdef EFL_HAVE_POSIX_THREADS -static pthread_mutex_t _mutex_big = PTHREAD_MUTEX_INITIALIZER; -#define SHARE_COMMON_LOCK_BIG() if(_share_common_threads_activated) \ - pthread_mutex_lock(&_mutex_big) -#define SHARE_COMMON_UNLOCK_BIG() if(_share_common_threads_activated) \ - pthread_mutex_unlock(&_mutex_big) -#else /* EFL_HAVE_WIN32_THREADS */ -static HANDLE _mutex_big = NULL; -#define SHARE_COMMON_LOCK_BIG() if(_share_common_threads_activated) \ - WaitForSingleObject(_mutex_big, INFINITE) -#define SHARE_COMMON_UNLOCK_BIG() if(_share_common_threads_activated) \ - ReleaseMutex(_mutex_big) - -#endif /* EFL_HAVE_WIN32_THREADS */ -#else /* EFL_HAVE_THREADS */ -#define SHARE_COMMON_LOCK_BIG() do {} while (0) -#define SHARE_COMMON_UNLOCK_BIG() do {} while (0) -#endif - -#ifdef EINA_SHARE_COMMON_USAGE -struct _Eina_Share_Common_Population { - int count; - int max; -}; - -static Eina_Share_Common_Population population = { 0, 0 }; - -static Eina_Share_Common_Population population_group[4] = { - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0} -}; - -static void _eina_share_common_population_init(Eina_Share * share) -{ - unsigned int i; - - for (i = 0; - i < sizeof(share->population_group) / - sizeof(share->population_group[0]); ++i) { - share->population_group[i].count = 0; - share->population_group[i].max = 0; - } -} - -static void _eina_share_common_population_shutdown(Eina_Share * share) -{ - unsigned int i; - - share->max_node_population = 0; - share->population.count = 0; - share->population.max = 0; - - for (i = 0; - i < sizeof(share->population_group) / - sizeof(share->population_group[0]); ++i) { - share->population_group[i].count = 0; - share->population_group[i].max = 0; - } -} - -static void _eina_share_common_population_stats(Eina_Share * share) -{ - unsigned int i; - - fprintf(stderr, "eina share_common statistic:\n"); - fprintf(stderr, - " * maximum shared strings : %i\n", share->population.max); - fprintf(stderr, - " * maximum shared strings per node : %i\n", - share->max_node_population); - - for (i = 0; - i < sizeof(share->population_group) / - sizeof(share->population_group[0]); ++i) - fprintf(stderr, - "DDD: %i strings of length %i, max strings: %i\n", - share->population_group[i].count, - i, share->population_group[i].max); -} - -void eina_share_common_population_add(Eina_Share * share, int slen) -{ - SHARE_COMMON_LOCK_BIG(); - - share->population.count++; - if (share->population.count > share->population.max) - share->population.max = share->population.count; - - if (slen < 4) { - share->population_group[slen].count++; - if (share->population_group[slen].count > - share->population_group[slen].max) - share->population_group[slen].max = - share->population_group[slen].count; - } - - SHARE_COMMON_UNLOCK_BIG(); -} - -void eina_share_common_population_del(Eina_Share * share, int slen) -{ - SHARE_COMMON_LOCK_BIG(); - - share->population.count--; - if (slen < 4) - share->population_group[slen].count--; - - SHARE_COMMON_UNLOCK_BIG(); -} - -static void -_eina_share_common_population_head_init(Eina_Share * share, - Eina_Share_Common_Head * head) -{ - head->population = 1; -} - -static void -_eina_share_common_population_head_add(Eina_Share * share, - Eina_Share_Common_Head * head) -{ - head->population++; - if (head->population > share->max_node_population) - share->max_node_population = head->population; -} - -static void -_eina_share_common_population_head_del(Eina_Share * share, - Eina_Share_Common_Head * head) -{ - head->population--; -} - -#else /* EINA_SHARE_COMMON_USAGE undefined */ - -static void _eina_share_common_population_init(__UNUSED__ Eina_Share * - share) -{ -} - -static void _eina_share_common_population_shutdown(__UNUSED__ Eina_Share * - share) -{ -} - -static void _eina_share_common_population_stats(__UNUSED__ Eina_Share * - share) -{ -} - -void eina_share_common_population_add(__UNUSED__ Eina_Share * share, - __UNUSED__ int slen) -{ -} - -void eina_share_common_population_del(__UNUSED__ Eina_Share * share, - __UNUSED__ int slen) -{ -} - -static void _eina_share_common_population_head_init(__UNUSED__ Eina_Share * - share, - __UNUSED__ - Eina_Share_Common_Head - * head) -{ -} - -static void _eina_share_common_population_head_add(__UNUSED__ Eina_Share * - share, - __UNUSED__ - Eina_Share_Common_Head * - head) -{ -} - -static void _eina_share_common_population_head_del(__UNUSED__ Eina_Share * - share, - __UNUSED__ - Eina_Share_Common_Head * - head) -{ -} -#endif - -static int -_eina_share_common_cmp(const Eina_Share_Common_Head * ed, - const int *hash, - __UNUSED__ int length, __UNUSED__ void *data) -{ - EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed,, 0); - - return ed->hash - *hash; -} - -static Eina_Rbtree_Direction -_eina_share_common_node(const Eina_Share_Common_Head * left, - const Eina_Share_Common_Head * right, - __UNUSED__ void *data) -{ - EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(left,, 0); - EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(right,, 0); - - if (left->hash - right->hash < 0) - return EINA_RBTREE_LEFT; - - return EINA_RBTREE_RIGHT; -} - -static void -_eina_share_common_head_free(Eina_Share_Common_Head * ed, - __UNUSED__ void *data) -{ - EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed,); - - while (ed->head) { - Eina_Share_Common_Node *el = ed->head; - - ed->head = ed->head->next; - if (el != &ed->builtin_node) - MAGIC_FREE(el); - } - MAGIC_FREE(ed); -} - -static void -_eina_share_common_node_init(Eina_Share_Common_Node * node, - const char *str, - int slen, - unsigned int null_size, Eina_Magic node_magic) -{ - EINA_MAGIC_SET(node, node_magic); - node->references = 1; - node->length = slen; - memcpy(node->str, str, slen); - memset(node->str + slen, 0, null_size); /* Nullify the null */ - - (void) node_magic; /* When magic are disable, node_magic is unused, this remove a warning. */ -} - -static Eina_Share_Common_Head *_eina_share_common_head_alloc(int slen) -{ - Eina_Share_Common_Head *head; - const size_t head_size = - offsetof(Eina_Share_Common_Head, builtin_node.str); - - head = malloc(head_size + slen); - if (!head) - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - - return head; -} - -static const char *_eina_share_common_add_head(Eina_Share * share, - Eina_Share_Common_Head ** - p_bucket, int hash, - const char *str, - unsigned int slen, - unsigned int null_size) -{ - Eina_Rbtree **p_tree = (Eina_Rbtree **) p_bucket; - Eina_Share_Common_Head *head; - - head = _eina_share_common_head_alloc(slen + null_size); - if (!head) - return NULL; - - EINA_MAGIC_SET(head, EINA_MAGIC_SHARE_HEAD); - head->hash = hash; - head->head = &head->builtin_node; - _eina_share_common_node_init(head->head, - str, - slen, null_size, share->node_magic); - head->head->next = NULL; - - _eina_share_common_population_head_init(share, head); - - *p_tree = eina_rbtree_inline_insert - (*p_tree, EINA_RBTREE_GET(head), - EINA_RBTREE_CMP_NODE_CB(_eina_share_common_node), NULL); - - return head->head->str; -} - -static void -_eina_share_common_del_head(Eina_Share_Common_Head ** p_bucket, - Eina_Share_Common_Head * head) -{ - Eina_Rbtree **p_tree = (Eina_Rbtree **) p_bucket; - - *p_tree = eina_rbtree_inline_remove - (*p_tree, EINA_RBTREE_GET(head), - EINA_RBTREE_CMP_NODE_CB(_eina_share_common_node), NULL); - - MAGIC_FREE(head); -} - - -static inline Eina_Bool -_eina_share_common_node_eq(const Eina_Share_Common_Node * node, - const char *str, unsigned int slen) -{ - return ((node->length == slen) && - (memcmp(node->str, str, slen) == 0)); -} - -static Eina_Share_Common_Node - *_eina_share_common_head_find(Eina_Share_Common_Head * head, - const char *str, unsigned int slen) -{ - Eina_Share_Common_Node *node, *prev; - - node = head->head; - if (_eina_share_common_node_eq(node, str, slen)) - return node; - - prev = node; - node = node->next; - for (; node; prev = node, node = node->next) - if (_eina_share_common_node_eq(node, str, slen)) { - /* promote node, make hot items be at the beginning */ - prev->next = node->next; - node->next = head->head; - head->head = node; - return node; - } - - return NULL; -} - -static Eina_Bool -_eina_share_common_head_remove_node(Eina_Share_Common_Head * head, - const Eina_Share_Common_Node * node) -{ - Eina_Share_Common_Node *cur, *prev; - - if (head->head == node) { - head->head = node->next; - return 1; - } - - prev = head->head; - cur = head->head->next; - for (; cur; prev = cur, cur = cur->next) - if (cur == node) { - prev->next = cur->next; - return 1; - } - - return 0; -} - -static Eina_Share_Common_Head - *_eina_share_common_find_hash(Eina_Share_Common_Head * bucket, - int hash) -{ - return (Eina_Share_Common_Head *) eina_rbtree_inline_lookup - (EINA_RBTREE_GET(bucket), &hash, 0, - EINA_RBTREE_CMP_KEY_CB(_eina_share_common_cmp), NULL); -} - -static Eina_Share_Common_Node *_eina_share_common_node_alloc(unsigned int - slen, - unsigned int - null_size) -{ - Eina_Share_Common_Node *node; - const size_t node_size = offsetof(Eina_Share_Common_Node, str); - - node = malloc(node_size + slen + null_size); - if (!node) - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - - return node; -} - -static Eina_Share_Common_Node *_eina_share_common_node_from_str(const char - *str, - Eina_Magic - node_magic) -{ - Eina_Share_Common_Node *node; - const size_t offset = offsetof(Eina_Share_Common_Node, str); - - node = (Eina_Share_Common_Node *) (str - offset); - EINA_MAGIC_CHECK_SHARE_COMMON_NODE(node, node_magic,); - return node; - - (void) node_magic; /* When magic are disable, node_magic is unused, this remove a warning. */ -} - -static Eina_Bool -eina_iterator_array_check(const Eina_Rbtree * rbtree __UNUSED__, - Eina_Share_Common_Head * head, - struct dumpinfo *fdata) -{ - Eina_Share_Common_Node *node; - - SHARE_COMMON_LOCK_BIG(); - - fdata->used += sizeof(Eina_Share_Common_Head); - for (node = head->head; node; node = node->next) { - printf("DDD: %5i %5i ", node->length, node->references); - printf("'%.*s'\n", node->length, - ((char *) node) + sizeof(Eina_Share_Common_Node)); - fdata->used += sizeof(Eina_Share_Common_Node); - fdata->used += node->length; - fdata->saved += (node->references - 1) * node->length; - fdata->dups += node->references - 1; - fdata->unique++; - } - - SHARE_COMMON_UNLOCK_BIG(); - - return EINA_TRUE; -} - -/** - * @endcond - */ - - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the share_common module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool -eina_share_common_init(Eina_Share ** _share, - Eina_Magic node_magic, const char *node_magic_STR) -{ - Eina_Share *share; - share = *_share = calloc(sizeof(Eina_Share), 1); - if (!share) - return EINA_FALSE; - - if (_eina_share_common_log_dom < 0) /*Only register if not already */ - _eina_share_common_log_dom = - eina_log_domain_register("eina_share", - EINA_LOG_COLOR_DEFAULT); - - if (_eina_share_common_log_dom < 0) { - EINA_LOG_ERR - ("Could not register log domain: eina_share_common"); - return EINA_FALSE; - } - - share->share = calloc(1, sizeof(Eina_Share_Common)); - if (!share->share) { - if (_eina_share_common_log_dom > 0) { - eina_log_domain_unregister - (_eina_share_common_log_dom); - _eina_share_common_log_dom = -1; - } - - return EINA_FALSE; - } - - share->node_magic = node_magic; -#define EMS(n) eina_magic_string_static_set(n, n ## _STR) - EMS(EINA_MAGIC_SHARE); - EMS(EINA_MAGIC_SHARE_HEAD); - EMS(node_magic); -#undef EMS - EINA_MAGIC_SET(share->share, EINA_MAGIC_SHARE); - - _eina_share_common_population_init(share); - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the share_common module set up by - * eina_share_common_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_share_common_shutdown(Eina_Share ** _share) -{ - unsigned int i; - Eina_Share *share = *_share; - - SHARE_COMMON_LOCK_BIG(); - - _eina_share_common_population_stats(share); - - /* remove any string still in the table */ - for (i = 0; i < EINA_SHARE_COMMON_BUCKETS; i++) { - eina_rbtree_delete(EINA_RBTREE_GET - (share->share->buckets[i]), - EINA_RBTREE_FREE_CB - (_eina_share_common_head_free), NULL); - share->share->buckets[i] = NULL; - } - MAGIC_FREE(share->share); - - _eina_share_common_population_shutdown(share); - if (_eina_share_common_log_dom > 0) { /* Only free if necessary */ - eina_log_domain_unregister(_eina_share_common_log_dom); - _eina_share_common_log_dom = -1; - } - - SHARE_COMMON_UNLOCK_BIG(); - - free(*_share); - *_share = NULL; - return EINA_TRUE; -} - -#ifdef EFL_HAVE_THREADS - -/** - * @internal - * @brief Activate the share_common mutexes. - * - * This function activate the mutexes in the eina share_common module. It is called by - * eina_threads_init(). - * - * @see eina_threads_init() - */ -void eina_share_common_threads_init(void) -{ - _share_common_threads_activated = EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the share_common mutexes. - * - * This function shuts down the mutexes in the share_common module. - * It is called by eina_threads_shutdown(). - * - * @see eina_threads_shutdown() - */ -void eina_share_common_threads_shutdown(void) -{ - _share_common_threads_activated = EINA_FALSE; -} - -#endif - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -const char *eina_share_common_add_length(Eina_Share * share, - const char *str, - unsigned int slen, - unsigned int null_size) -{ - Eina_Share_Common_Head **p_bucket, *ed; - Eina_Share_Common_Node *el; - int hash_num, hash; - - if (!str) - return NULL; - - eina_share_common_population_add(share, slen); - - if (slen <= 0) - return NULL; - - hash = eina_hash_superfast(str, slen); - hash_num = hash & 0xFF; - hash = (hash >> 8) & EINA_SHARE_COMMON_MASK; - - SHARE_COMMON_LOCK_BIG(); - p_bucket = share->share->buckets + hash_num; - - ed = _eina_share_common_find_hash(*p_bucket, hash); - if (!ed) { - const char *s = _eina_share_common_add_head(share, - p_bucket, - hash, - str, - slen, - null_size); - SHARE_COMMON_UNLOCK_BIG(); - return s; - } - - EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, SHARE_COMMON_UNLOCK_BIG(), - NULL); - - el = _eina_share_common_head_find(ed, str, slen); - if (el) { - EINA_MAGIC_CHECK_SHARE_COMMON_NODE(el, - share->node_magic, - SHARE_COMMON_UNLOCK_BIG - ()); - el->references++; - SHARE_COMMON_UNLOCK_BIG(); - return el->str; - } - - el = _eina_share_common_node_alloc(slen, null_size); - if (!el) { - SHARE_COMMON_UNLOCK_BIG(); - return NULL; - } - - _eina_share_common_node_init(el, str, slen, null_size, - share->node_magic); - el->next = ed->head; - ed->head = el; - _eina_share_common_population_head_add(share, ed); - - SHARE_COMMON_UNLOCK_BIG(); - - return el->str; -} - -const char *eina_share_common_ref(Eina_Share * share, const char *str) -{ - Eina_Share_Common_Node *node; - - if (!str) - return NULL; - - SHARE_COMMON_LOCK_BIG(); - node = _eina_share_common_node_from_str(str, share->node_magic); - node->references++; - DBG("str=%p refs=%u", str, node->references); - - SHARE_COMMON_UNLOCK_BIG(); - - eina_share_common_population_add(share, node->length); - - return str; -} - - -void eina_share_common_del(Eina_Share * share, const char *str) -{ - unsigned int slen; - Eina_Share_Common_Head *ed; - Eina_Share_Common_Head **p_bucket; - Eina_Share_Common_Node *node; - int hash_num, hash; - - if (!str) - return; - - SHARE_COMMON_LOCK_BIG(); - - node = _eina_share_common_node_from_str(str, share->node_magic); - slen = node->length; - eina_share_common_population_del(share, slen); - if (node->references > 1) { - node->references--; - DBG("str=%p refs=%u", str, node->references); - SHARE_COMMON_UNLOCK_BIG(); - return; - } - - DBG("str=%p refs=0, delete.", str); - node->references = 0; - - hash = eina_hash_superfast(str, slen); - hash_num = hash & 0xFF; - hash = (hash >> 8) & EINA_SHARE_COMMON_MASK; - - p_bucket = share->share->buckets + hash_num; - ed = _eina_share_common_find_hash(*p_bucket, hash); - if (!ed) - goto on_error; - - EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, SHARE_COMMON_UNLOCK_BIG()); - - if (!_eina_share_common_head_remove_node(ed, node)) - goto on_error; - - if (node != &ed->builtin_node) - MAGIC_FREE(node); - - if (!ed->head) - _eina_share_common_del_head(p_bucket, ed); - else - _eina_share_common_population_head_del(share, ed); - - SHARE_COMMON_UNLOCK_BIG(); - - return; - - on_error: - SHARE_COMMON_UNLOCK_BIG(); - /* possible segfault happened before here, but... */ - CRITICAL("EEEK trying to del non-shared share_common \"%s\"", str); -} - -int -eina_share_common_length(__UNUSED__ Eina_Share * share, const char *str) -{ - const Eina_Share_Common_Node *node; - - if (!str) - return -1; - - node = _eina_share_common_node_from_str(str, share->node_magic); - return node->length; -} - -void -eina_share_common_dump(Eina_Share * share, - void (*additional_dump) (struct dumpinfo *), - int used) -{ - Eina_Iterator *it; - unsigned int i; - struct dumpinfo di; - - if (!share) - return; - - di.used = used; - di.saved = 0; - di.dups = 0; - di.unique = 0; - printf("DDD: len ref string\n"); - printf("DDD:-------------------\n"); - - SHARE_COMMON_LOCK_BIG(); - for (i = 0; i < EINA_SHARE_COMMON_BUCKETS; i++) { - if (!share->share->buckets[i]) { - continue; // printf("DDD: BUCKET # %i (HEAD=%i, NODE=%i)\n", i, - - } -// sizeof(Eina_Share_Common_Head), sizeof(Eina_Share_Common_Node)); - it = eina_rbtree_iterator_prefix((Eina_Rbtree *) share-> - share->buckets[i]); - eina_iterator_foreach(it, - EINA_EACH_CB - (eina_iterator_array_check), &di); - eina_iterator_free(it); - } - if (additional_dump) - additional_dump(&di); - -#ifdef EINA_SHARE_COMMON_USAGE - /* One character strings are not counted in the hash. */ - di.saved += share->population_group[0].count * sizeof(char); - di.saved += share->population_group[1].count * sizeof(char) * 2; -#endif - printf("DDD:-------------------\n"); - printf("DDD: usage (bytes) = %i, saved = %i (%3.0f%%)\n", - di.used, di.saved, - di.used ? (di.saved * 100.0 / di.used) : 0.0); - printf("DDD: unique: %d, duplicates: %d (%3.0f%%)\n", di.unique, - di.dups, di.unique ? (di.dups * 100.0 / di.unique) : 0.0); - -#ifdef EINA_SHARE_COMMON_USAGE - printf("DDD: Allocated strings: %i\n", share->population.count); - printf("DDD: Max allocated strings: %i\n", share->population.max); - - for (i = 0; - i < sizeof(share->population_group) / - sizeof(share->population_group[0]); ++i) - fprintf(stderr, - "DDD: %i strings of length %i, max strings: %i\n", - share->population_group[i].count, - i, share->population_group[i].max); -#endif - - SHARE_COMMON_UNLOCK_BIG(); -} - -/** - * @endcond - */ diff --git a/tests/suite/ecore/src/lib/eina_share_common.h b/tests/suite/ecore/src/lib/eina_share_common.h deleted file mode 100644 index 63c1f9277d..0000000000 --- a/tests/suite/ecore/src/lib/eina_share_common.h +++ /dev/null @@ -1,103 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, Jorge Luis Zapata Muga, 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 <https://www.gnu.org/licenses/>. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (C) 2008 Peter Wehrfritz - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies of the Software and its Copyright notices. In addition publicly - * documented acknowledgment must be given that this software has been used if no - * source code of this software is made available publicly. This includes - * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing - * documents or any documentation provided with any product containing this - * software. This License does not apply to any software that links to the - * libraries provided by this software (statically or dynamically), but only to - * the software provided. - * - * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice - * and it's intent. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef EINA_SHARE_COMMON_H_ -#define EINA_SHARE_COMMON_H_ - -#include "eina_types.h" -#include "eina_magic.h" - -typedef struct _Eina_Share Eina_Share; - -struct dumpinfo { - int used, saved, dups, unique; -}; - -Eina_Bool eina_share_common_init(Eina_Share ** share, - Eina_Magic node_magic, - const char *node_magic_STR); -Eina_Bool eina_share_common_shutdown(Eina_Share ** share); -const char *eina_share_common_add_length(Eina_Share * share, - const char *str, - unsigned int slen, - unsigned int null_size) - EINA_WARN_UNUSED_RESULT; -const char *eina_share_common_ref(Eina_Share * share, const char *str); -void eina_share_common_del(Eina_Share * share, const char *str); -int eina_share_common_length(Eina_Share * share, - const char *str) EINA_CONST - EINA_WARN_UNUSED_RESULT; -void eina_share_common_dump(Eina_Share * share, - void (*additional_dump) (struct dumpinfo *), - int used); - - -/* Population functions */ -void eina_share_common_population_add(Eina_Share * share, int slen); -void eina_share_common_population_del(Eina_Share * share, int slen); - -/* Share logging */ -#ifdef CRITICAL -#undef CRITICAL -#endif -#define CRITICAL(...) EINA_LOG_DOM_CRIT(_eina_share_common_log_dom, __VA_ARGS__) - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_share_common_log_dom, __VA_ARGS__) - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eina_share_common_log_dom, __VA_ARGS__) -extern int _eina_share_common_log_dom; - -#endif /* EINA_STRINGSHARE_H_ */ diff --git a/tests/suite/ecore/src/lib/eina_str.c b/tests/suite/ecore/src/lib/eina_str.c deleted file mode 100644 index 13cecfb3fc..0000000000 --- a/tests/suite/ecore/src/lib/eina_str.c +++ /dev/null @@ -1,594 +0,0 @@ -/* Leave the OpenBSD version below so we can track upstream fixes */ -/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <ctype.h> - -#ifdef HAVE_ICONV -#include <errno.h> -#include <iconv.h> -#endif - -#include "eina_private.h" -#include "eina_str.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -/* - * Internal helper function used by eina_str_has_suffix() and - * eina_str_has_extension() - */ -static inline Eina_Bool -eina_str_has_suffix_helper(const char *str, - const char *suffix, - int (*cmp) (const char *, const char *)) -{ - size_t str_len; - size_t suffix_len; - - str_len = strlen(str); - suffix_len = eina_strlen_bounded(suffix, str_len); - if (suffix_len == (size_t) - 1) - return EINA_FALSE; - - return cmp(str + str_len - suffix_len, suffix) == 0; -} - -static inline char **eina_str_split_full_helper(const char *str, - const char *delim, - int max_tokens, - unsigned int *elements) -{ - char *s, **str_array; - const char *src; - size_t len, dlen; - unsigned int tokens; - - dlen = strlen(delim); - if (dlen == 0) { - if (elements) - *elements = 0; - - return NULL; - } - - tokens = 0; - src = str; - /* count tokens and check strlen(str) */ - while (*src != '\0') { - const char *d = delim, *d_end = d + dlen; - const char *tmp = src; - for (; (d < d_end) && (*tmp != '\0'); d++, tmp++) { - if (EINA_LIKELY(*d != *tmp)) - break; - } - if (EINA_UNLIKELY(d == d_end)) { - src = tmp; - tokens++; - } else - src++; - } - len = src - str; - - if ((max_tokens > 0) && (tokens > (unsigned int) max_tokens)) - tokens = max_tokens; - - str_array = malloc(sizeof(char *) * (tokens + 2)); - if (!str_array) { - if (elements) - *elements = 0; - - return NULL; - } - - s = malloc(len + 1); - if (!s) { - free(str_array); - if (elements) - *elements = 0; - - return NULL; - } - - /* copy tokens and string */ - tokens = 0; - str_array[0] = s; - src = str; - while (*src != '\0') { - const char *d = delim, *d_end = d + dlen; - const char *tmp = src; - for (; (d < d_end) && (*tmp != '\0'); d++, tmp++) { - if (EINA_LIKELY(*d != *tmp)) - break; - } - if (EINA_UNLIKELY(d == d_end)) { - src = tmp; - *s = '\0'; - s += dlen; - tokens++; - str_array[tokens] = s; - } else { - *s = *src; - s++; - src++; - } - } - *s = '\0'; - str_array[tokens + 1] = NULL; - if (elements) - *elements = (tokens + 1); - - return str_array; -} - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_String_Group String - * - * @brief These functions provide useful C string management. - * - * @{ - */ - - -/** - * @brief Copy a c-string to another. - * - * @param dst The destination string. - * @param src The source string. - * @param siz The size of the destination string. - * @return The length of the source string. - * - * This function copies up to @p siz - 1 characters from the - * NUL-terminated string @p src to @p dst, NUL-terminating the result - * (unless @p siz is equal to 0). The returned value is the length of - * @p src. If the returned value is greater than @p siz, truncation - * occurred. - */ -EAPI size_t eina_strlcpy(char *dst, const char *src, size_t siz) -{ -#ifdef HAVE_STRLCPY - return strlcpy(dst, src, siz); -#else - char *d = dst; - const char *s = src; - size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0) - while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - - while (*s++); - } - - return (s - src - 1); /* count does not include NUL */ -#endif -} - -/** - * @brief Append a c-string. - * - * @param dst The destination string. - * @param src The source string. - * @param siz The size of the destination string. - * @return The length of the source string plus MIN(siz, strlen(initial dst)) - * - * This function appends @p src to @p dst of size @p siz (unlike - * strncat, @p siz is the full size of @p dst, not space left). At - * most @p siz - 1 characters will be copied. Always NUL terminates - * (unless @p siz <= strlen(dst)). This function returns strlen(src) + - * MIN(siz, strlen(initial dst)). If the returned value is greater or - * equal than @p siz, truncation occurred. - */ -EAPI size_t eina_strlcat(char *dst, const char *src, size_t siz) -{ - char *d = dst; - const char *s = src; - size_t n = siz; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - dlen = d - dst; - n = siz - dlen; - - if (n == 0) - return (dlen + strlen(s)); - - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - - s++; - } - *d = '\0'; - - return (dlen + (s - src)); /* count does not include NUL */ -} - -/** - * @brief Check if the given string has the given prefix. - * - * @param str The string to work with. - * @param prefix The prefix to check for. - * @return #EINA_TRUE if the string has the given prefix, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if @p str has the prefix - * @p prefix, #EINA_FALSE otherwise. If the length of @p prefix is - * greater than @p str, #EINA_FALSE is returned. - */ -EAPI Eina_Bool eina_str_has_prefix(const char *str, const char *prefix) -{ - size_t str_len; - size_t prefix_len; - - str_len = strlen(str); - prefix_len = eina_strlen_bounded(prefix, str_len); - if (prefix_len == (size_t) - 1) - return EINA_FALSE; - - return (strncmp(str, prefix, prefix_len) == 0); -} - -/** - * @brief Check if the given string has the given suffix. - * - * @param str The string to work with. - * @param suffix The suffix to check for. - * @return #EINA_TRUE if the string has the given suffix, #EINA_FALSE otherwise. - * - * This function returns #EINA_TRUE if @p str has the suffix - * @p suffix, #EINA_FALSE otherwise. If the length of @p suffix is - * greater than @p str, #EINA_FALSE is returned. - */ -/** - * @param str the string to work with - * @param suffix the suffix to check for - * @return true if str has the given suffix - * @brief checks if the string has the given suffix - */ -EAPI Eina_Bool eina_str_has_suffix(const char *str, const char *suffix) -{ - return eina_str_has_suffix_helper(str, suffix, strcmp); -} - -/** - * @brief Check if the given string has the given suffix. - * - * @param str The string to work with. - * @param ext The extension to check for. - * @return #EINA_TRUE if the string has the given extension, #EINA_FALSE otherwise. - * - * This function does the same like eina_str_has_suffix(), but with a - * case insensitive compare. - */ -EAPI Eina_Bool eina_str_has_extension(const char *str, const char *ext) -{ - return eina_str_has_suffix_helper(str, ext, strcasecmp); -} - -/** - * @brief Split a string using a delimiter and returns number of elements. - * - * @param str The string to split. - * @param delim The string which specifies the places at which to split the string. - * @param max_tokens The maximum number of strings to split string into. - * @param elements Where to return the number of elements in returned - * array (not counting the terminating @c NULL). May be @c NULL. - * @return A newly-allocated NULL-terminated array of strings or NULL if it - * fails to allocate the array. - * - * This functin splits @p str into a maximum of @p max_tokens pieces, - * using the given delimiter @p delim. @p delim is not included in any - * of the resulting strings, unless @p max_tokens is reached. If - * @p max_tokens is less than @c 1, the string is splitted completely. If - * @p max_tokens is reached, the last string in the returned string - * array contains the remainder of string. The returned value is a - * newly allocated NULL-terminated array of strings or NULL if it fails to - * allocate the array. To free it, free the first element of the array and the - * array itself. - * - * @see eina_str_split() - */ -EAPI char **eina_str_split_full(const char *str, - const char *delim, - int max_tokens, unsigned int *elements) -{ - return eina_str_split_full_helper(str, delim, max_tokens, - elements); -} - - -/** - * @brief Split a string using a delimiter. - * - * @param str The string to split. - * @param delim The string which specifies the places at which to split the string. - * @param max_tokens The maximum number of strings to split string into. - * @return A newly-allocated NULL-terminated array of strings or NULL if it - * fails to allocate the array. - * - * This functin splits @p str into a maximum of @p max_tokens pieces, - * using the given delimiter @p delim. @p delim is not included in any - * of the resulting strings, unless @p max_tokens is reached. If - * @p max_tokens is less than @c 1, the string is splitted completely. If - * @p max_tokens is reached, the last string in the returned string - * array contains the remainder of string. The returned value is a - * newly allocated NULL-terminated array of strings or NULL if it fails to - * allocate the array. To free it, free the first element of the array and the - * array itself. - */ -EAPI char **eina_str_split(const char *str, const char *delim, - int max_tokens) -{ - return eina_str_split_full_helper(str, delim, max_tokens, NULL); -} - -/** - * @brief Join two strings of known length. - * - * @param dst The buffer to store the result. - * @param size Size (in byte) of the buffer. - * @param sep The separator character to use. - * @param a First string to use, before @p sep. - * @param a_len length of @p a. - * @param b Second string to use, after @p sep. - * @param b_len length of @p b. - * @return The number of characters printed. - * - * This function joins the strings @p a and @p b (in that order) and - * separate them with @p sep. The result is stored in the buffer - * @p dst and at most @p size - 1 characters will be written and the - * string is NULL-terminated. @p a_len is the length of @p a (not - * including '\\0') and @p b_len is the length of @p b (not including - * '\\0'). This function returns the number of characters printed (not - * including the trailing '\\0' used to end output to strings). Just - * like snprintf(), it will not write more than @p size bytes, thus a - * returned value of @p size or more means that the output was - * truncated. - * - * @see eina_str_join() - * @see eina_str_join_static() - */ -EAPI size_t -eina_str_join_len(char *dst, - size_t size, - char sep, - const char *a, size_t a_len, const char *b, size_t b_len) -{ - size_t ret = a_len + b_len + 1; - size_t off; - - if (size < 1) - return ret; - - if (size <= a_len) { - memcpy(dst, a, size - 1); - dst[size - 1] = '\0'; - return ret; - } - - memcpy(dst, a, a_len); - off = a_len; - - if (size <= off + 1) { - dst[size - 1] = '\0'; - return ret; - } - - dst[off] = sep; - off++; - - if (size <= off + b_len + 1) { - memcpy(dst + off, b, size - off - 1); - dst[size - 1] = '\0'; - return ret; - } - - memcpy(dst + off, b, b_len); - dst[off + b_len] = '\0'; - return ret; -} - -/** - * @brief Use iconv to convert a text string from one encoding to another - * - * @param enc_from encoding to convert from - * @param enc_to encoding to convert to - * @param text text to convert - * - */ -#ifdef HAVE_ICONV -EAPI char *eina_str_convert(const char *enc_from, const char *enc_to, - const char *text) -{ - iconv_t ic; - char *new_txt, *inp, *outp; - size_t inb, outb, outlen, tob, outalloc; - - if (!text) - return NULL; - - ic = iconv_open(enc_to, enc_from); - if (ic == (iconv_t) (-1)) - return NULL; - - new_txt = malloc(64); - inb = strlen(text); - outb = 64; - inp = (char *) text; - outp = new_txt; - outalloc = 64; - outlen = 0; - - for (;;) { - size_t count; - - tob = outb; - count = iconv(ic, &inp, &inb, &outp, &outb); - outlen += tob - outb; - if (count == (size_t) (-1)) { - if (errno == E2BIG) { - new_txt = realloc(new_txt, outalloc + 64); - outp = new_txt + outlen; - outalloc += 64; - outb += 64; - } else if (errno == EILSEQ) { - if (new_txt) - free(new_txt); - - new_txt = NULL; - break; - } else if (errno == EINVAL) { - if (new_txt) - free(new_txt); - - new_txt = NULL; - break; - } else { - if (new_txt) - free(new_txt); - - new_txt = NULL; - break; - } - } - - if (inb == 0) { - if (outalloc == outlen) - new_txt = realloc(new_txt, outalloc + 1); - - new_txt[outlen] = 0; - break; - } - } - iconv_close(ic); - return new_txt; -} -#else -EAPI char *eina_str_convert(const char *enc_from __UNUSED__, - const char *enc_to __UNUSED__, - const char *text __UNUSED__) -{ - return NULL; -} -#endif - -/** - * @brief Put a \ before and Space( ), \ or ' in a string. - * - * @param str the string to escape - * - * A newly allocated string is returned. - */ -EAPI char *eina_str_escape(const char *str) -{ - char *s2, *d; - const char *s; - - s2 = malloc((strlen(str) * 2) + 1); - if (!s2) - return NULL; - - for (s = str, d = s2; *s != 0; s++, d++) { - if ((*s == ' ') || (*s == '\\') || (*s == '\'')) { - *d = '\\'; - d++; - } - - *d = *s; - } - *d = 0; - return s2; -} - -/** - * @brief Lowercase all the characters in range [A-Z] in the given string. - * - * @param str the string to lowercase - * - * This modifies the original string, changing all characters in [A-Z] to lowercase. - */ -EAPI void eina_str_tolower(char **str) -{ - char *p; - if ((!str) || (!(*str))) - return; - - for (p = *str; (*p); p++) - *p = tolower((unsigned char) (*p)); -} - -/** - * @brief Uppercase all the characters in range [a-z] in the given string. - * - * @param str the string to uppercase - * - * This modifies the original string, changing all characters in [a-z] to uppercase. - */ -EAPI void eina_str_toupper(char **str) -{ - char *p; - if ((!str) || (!(*str))) - return; - - for (p = *str; (*p); p++) - *p = toupper((unsigned char) (*p)); -} - - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_strbuf.c b/tests/suite/ecore/src/lib/eina_strbuf.c deleted file mode 100644 index 338d056d86..0000000000 --- a/tests/suite/ecore/src/lib/eina_strbuf.c +++ /dev/null @@ -1,180 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _GNU_SOURCE - -#include <stdio.h> -#include <string.h> - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_private.h" -#include "eina_str.h" -#include "eina_strbuf_common.h" -#include "eina_unicode.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - -#ifdef _STRBUF_DATA_TYPE -#undef _STRBUF_DATA_TYPE -#endif - -#ifdef _STRBUF_CSIZE -#undef _STRBUF_CSIZE -#endif - -#ifdef _STRBUF_STRUCT_NAME -#undef _STRBUF_STRUCT_NAME -#endif - -#ifdef _STRBUF_STRLEN_FUNC -#undef _STRBUF_STRLEN_FUNC -#endif - -#ifdef _STRBUF_STRESCAPE_FUNC -#undef _STRBUF_STRESCAPE_FUNC -#endif - -#ifdef _STRBUF_MAGIC -#undef _STRBUF_MAGIC -#endif - -#ifdef _STRBUF_MAGIC_STR -#undef _STRBUF_MAGIC_STR -#endif - -#ifdef _FUNC_EXPAND -#undef _FUNC_EXPAND -#endif - - -#define _STRBUF_DATA_TYPE char -#define _STRBUF_CSIZE sizeof(_STRBUF_DATA_TYPE) -#define _STRBUF_STRUCT_NAME Eina_Strbuf -#define _STRBUF_STRLEN_FUNC(x) strlen(x) -#define _STRBUF_STRESCAPE_FUNC(x) eina_str_escape(x) -#define _STRBUF_MAGIC EINA_MAGIC_STRBUF -#define _STRBUF_MAGIC_STR __STRBUF_MAGIC_STR -static const char __STRBUF_MAGIC_STR[] = "Eina Strbuf"; - -#define _FUNC_EXPAND(y) eina_strbuf_ ## y - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - - -/*============================================================================* - * API * - *============================================================================*/ - - -/** - * @addtogroup Eina_String_Buffer_Group String Buffer - * - * @brief These functions provide string buffers management. - * - * The String Buffer data type is designed to be a mutable string, - * allowing to append, prepend or insert a string to a buffer. - * - * @{ - */ - -EAPI Eina_Bool -eina_strbuf_append_printf(Eina_Strbuf * buf, const char *fmt, ...) -{ - va_list args; - char *str; - size_t len; - Eina_Bool ret; - - va_start(args, fmt); - len = vasprintf(&str, fmt, args); - va_end(args); - - if (len <= 0 || !str) - return EINA_FALSE; - - ret = eina_strbuf_append_length(buf, str, len); - free(str); - return ret; -} - -EAPI Eina_Bool -eina_strbuf_append_vprintf(Eina_Strbuf * buf, const char *fmt, - va_list args) -{ - char *str; - size_t len; - Eina_Bool ret; - - len = vasprintf(&str, fmt, args); - - if (len <= 0 || !str) - return EINA_FALSE; - - ret = eina_strbuf_append_length(buf, str, len); - free(str); - return ret; -} - -EAPI Eina_Bool -eina_strbuf_insert_printf(Eina_Strbuf * buf, const char *fmt, size_t pos, - ...) -{ - va_list args; - char *str; - size_t len; - Eina_Bool ret; - - va_start(args, pos); - len = vasprintf(&str, fmt, args); - va_end(args); - - if (len <= 0 || !str) - return EINA_FALSE; - - ret = eina_strbuf_insert(buf, str, pos); - free(str); - return ret; -} - -EAPI Eina_Bool -eina_strbuf_insert_vprintf(Eina_Strbuf * buf, - const char *fmt, size_t pos, va_list args) -{ - char *str; - size_t len; - Eina_Bool ret; - - len = vasprintf(&str, fmt, args); - - if (len <= 0 || !str) - return EINA_FALSE; - - ret = eina_strbuf_insert(buf, str, pos); - free(str); - return ret; -} - -/* Unicode */ - -#include "eina_strbuf_template_c.x" - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_strbuf_common.c b/tests/suite/ecore/src/lib/eina_strbuf_common.c deleted file mode 100644 index 9e3c09ded1..0000000000 --- a/tests/suite/ecore/src/lib/eina_strbuf_common.c +++ /dev/null @@ -1,834 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef _WIN32 -#include <Evil.h> -#endif - -#include "eina_private.h" -#include "eina_str.h" -#include "eina_magic.h" -#include "eina_error.h" -#include "eina_safety_checks.h" -#include "eina_strbuf.h" -#include "eina_strbuf_common.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/** - * @cond LOCAL - */ - -#define EINA_STRBUF_INIT_SIZE 32 -#define EINA_STRBUF_INIT_STEP 32 -#define EINA_STRBUF_MAX_STEP 4096 - -/** - * @endcond - */ - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the strbuf module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the strbuf module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_strbuf_common_init(void) -{ - return EINA_TRUE; -} - -/** - * @internal - * @brief Shut down the strbuf module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the strbuf module set up by - * eina_strbuf_common_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_strbuf_common_shutdown(void) -{ - return EINA_TRUE; -} - -/** - * @internal - * - * init the buffer - * @param buf the buffer to init - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -static Eina_Bool _eina_strbuf_common_init(size_t csize, Eina_Strbuf * buf) -{ - buf->len = 0; - buf->size = EINA_STRBUF_INIT_SIZE; - buf->step = EINA_STRBUF_INIT_STEP; - - eina_error_set(0); - buf->buf = calloc(csize, buf->size); - if (EINA_UNLIKELY(!buf->buf)) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -/** - * @internal - * - * resize the buffer - * @param buf the buffer to resize - * @param size the minimum size of the buffer - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -static inline Eina_Bool -_eina_strbuf_common_resize(size_t csize, Eina_Strbuf * buf, size_t size) -{ - size_t new_size, new_step, delta; - void *buffer; - - size += 1; // Add extra space for '\0' - - if (size == buf->size) - /* nothing to do */ - return EINA_TRUE; - else if (size > buf->size) - delta = size - buf->size; - else - delta = buf->size - size; - - /* check if should keep the same step (just used while growing) */ - if ((delta <= buf->step) && (size > buf->size)) - new_step = buf->step; - else { - new_step = (((delta / EINA_STRBUF_INIT_STEP) + 1) - * EINA_STRBUF_INIT_STEP); - - if (new_step > EINA_STRBUF_MAX_STEP) - new_step = EINA_STRBUF_MAX_STEP; - } - - new_size = (((size / new_step) + 1) * new_step); - - /* reallocate the buffer to the new size */ - buffer = realloc(buf->buf, new_size * csize); - if (EINA_UNLIKELY(!buffer)) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return EINA_FALSE; - } - - buf->buf = buffer; - buf->size = new_size; - buf->step = new_step; - eina_error_set(0); - return EINA_TRUE; -} - -/** - * @internal - * - * If required, enlarge the buffer to fit the new size. - * - * @param buf the buffer to resize - * @param size the minimum size of the buffer - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -Eina_Bool -_eina_strbuf_common_grow(size_t csize, Eina_Strbuf * buf, size_t size) -{ - if ((size + 1) < buf->size) - return EINA_TRUE; - - return _eina_strbuf_common_resize(csize, buf, size); -} - -/** - * @internal - * - * insert string of known length at random within existing strbuf limits. - * - * @param buf the buffer to resize, must be valid. - * @param str the string to copy, must be valid (!NULL and smaller than @a len) - * @param len the amount of bytes in @a str to copy, must be valid. - * @param pos the position inside buffer to insert, must be valid (smaller - * than eina_strbuf_common_length_get()) - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - */ -static inline Eina_Bool -_eina_strbuf_common_insert_length(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t len, size_t pos) -{ - if (EINA_UNLIKELY - (!_eina_strbuf_common_grow(csize, buf, buf->len + len))) - return EINA_FALSE; - - /* move the existing text */ - memmove(buf->buf + ((len + pos) * csize), buf->buf + (pos * csize), - (buf->len - pos) * csize); - - /* and now insert the given string */ - memcpy(buf->buf + (pos * csize), str, len * csize); - - buf->len += len; - memset(buf->buf + (buf->len * csize), 0, csize); - return EINA_TRUE; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @brief Create a new string buffer. - * - * @return Newly allocated string buffer instance. - * - * This function creates a new string buffer. On error, @c NULL is - * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To - * free the resources, use eina_strbuf_common_free(). - * - * @see eina_strbuf_common_free() - * @see eina_strbuf_common_append() - * @see eina_strbuf_common_string_get() - */ -Eina_Strbuf *eina_strbuf_common_new(size_t csize) -{ - Eina_Strbuf *buf; - - eina_error_set(0); - buf = malloc(sizeof(Eina_Strbuf)); - if (EINA_UNLIKELY(!buf)) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - if (EINA_UNLIKELY(!_eina_strbuf_common_init(csize, buf))) { - eina_strbuf_common_free(buf); - return NULL; - } - - return buf; -} - -/** - * @brief Free a string buffer. - * - * @param buf The string buffer to free. - * - * This function frees the memory of @p buf. @p buf must have been - * created by eina_strbuf_common_new(). - */ -void eina_strbuf_common_free(Eina_Strbuf * buf) -{ - free(buf->buf); - free(buf); -} - -/** - * @brief Reset a string buffer. - * - * @param buf The string buffer to reset. - * - * This function reset @p buf: the buffer len is set to 0, and the - * string is set to '\\0'. No memory is free'd. - */ -void eina_strbuf_common_reset(size_t csize, Eina_Strbuf * buf) -{ - buf->len = 0; - buf->step = EINA_STRBUF_INIT_STEP; - - memset(buf->buf, 0, csize); -} - -/** - * @brief Append a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. It computes the length of - * @p str, so is slightly slower than eina_strbuf_common_append_length(). If - * the length is known beforehand, consider using that variant. If - * @p buf can't append it, #EINA_FALSE is returned, otherwise - * #EINA_TRUE is returned. - * - * @see eina_strbuf_common_append() - * @see eina_strbuf_common_append_length() - */ -Eina_Bool -eina_strbuf_common_append(size_t csize, - Eina_Strbuf * buf, const void *str, size_t len) -{ - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - - if (EINA_UNLIKELY - (!_eina_strbuf_common_grow(csize, buf, buf->len + len))) - return EINA_FALSE; - - memcpy(buf->buf + (buf->len * csize), str, (len + 1) * csize); - buf->len += len; - return EINA_TRUE; -} - -/** - * @brief Append a string to a buffer, reallocating as necessary, - * limited by the given length. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param maxlen The maximum number of characters to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends at most @p maxlen characters of @p str to - * @p buf. It can't appends more than the length of @p str. It - * computes the length of @p str, so is slightly slower than - * eina_strbuf_common_append_length(). If the length is known beforehand, - * consider using that variant (@p maxlen should then be checked so - * that it is greater than the size of @p str). If @p str can not be - * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is - * returned. - * - * @see eina_strbuf_common_append() - * @see eina_strbuf_common_append_length() - */ -Eina_Bool -eina_strbuf_common_append_n(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t len, size_t maxlen) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - - if (len > maxlen) - len = maxlen; - - if (EINA_UNLIKELY - (!_eina_strbuf_common_grow(csize, buf, buf->len + len))) - return EINA_FALSE; - - memcpy(buf->buf + (buf->len * csize), str, len * csize); - buf->len += len; - memset(buf->buf + (buf->len * csize), 0, csize); - return EINA_TRUE; -} - -/** - * @brief Append a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to append to. - * @param str The string to append. - * @param length The exact length to use. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function appends @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_strbuf_common_append() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_strbuf_common_append() - * @see eina_strbuf_common_append_n() - */ -Eina_Bool -eina_strbuf_common_append_length(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t length) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - - if (EINA_UNLIKELY - (!_eina_strbuf_common_grow(csize, buf, buf->len + length))) - return EINA_FALSE; - - memcpy(buf->buf + (buf->len * csize), str, length * csize); - buf->len += length; - memset(buf->buf + (buf->len * csize), 0, csize); - return EINA_TRUE; -} - -/** - * @brief Insert a string to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert. - * @param str The string to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf at position @p pos. It - * computes the length of @p str, so is slightly slower than - * eina_strbuf_common_insert_length(). If the length is known beforehand, - * consider using that variant. If @p buf can't insert it, #EINA_FALSE - * is returned, otherwise #EINA_TRUE is returned. - */ -Eina_Bool -eina_strbuf_common_insert(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t len, size_t pos) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - - if (pos >= buf->len) - return eina_strbuf_common_append(csize, buf, str, len); - - return _eina_strbuf_common_insert_length(csize, buf, str, len, - pos); -} - -/** - * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param maxlen The maximum number of chars to insert. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str ot @p buf at position @p pos, with at - * most @p maxlen bytes. The number of inserted characters can not be - * greater than the length of @p str. It computes the length of - * @p str, so is slightly slower than eina_strbuf_common_insert_length(). If the - * length is known beforehand, consider using that variant (@p maxlen - * should then be checked so that it is greater than the size of - * @p str). If @p str can not be inserted, #EINA_FALSE is returned, - * otherwise, #EINA_TRUE is returned. - */ -Eina_Bool -eina_strbuf_common_insert_n(size_t csize, - Eina_Strbuf * buf, - const void *str, - size_t len, size_t maxlen, size_t pos) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - - if (pos >= buf->len) - return eina_strbuf_common_append_n(csize, buf, str, len, - maxlen); - - if (len > maxlen) - len = maxlen; - - return _eina_strbuf_common_insert_length(csize, buf, str, len, - pos); -} - -/** - * @brief Insert a string of exact length to a buffer, reallocating as necessary. - * - * @param buf The string buffer to insert to. - * @param str The string to insert. - * @param length The exact length to use. - * @param pos The position to insert the string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p str to @p buf. @p str must be of size at - * most @p length. It is slightly faster than eina_strbuf_common_insert() as - * it does not compute the size of @p str. It is useful when dealing - * with strings of known size, such as eina_strngshare. If @p buf - * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - * - * @see eina_stringshare_length() - * @see eina_strbuf_common_insert() - * @see eina_strbuf_common_insert_n() - */ -Eina_Bool -eina_strbuf_common_insert_length(size_t csize, - Eina_Strbuf * buf, - const void *str, - size_t length, size_t pos) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - - if (pos >= buf->len) - return eina_strbuf_common_append_length(csize, buf, str, - length); - - return _eina_strbuf_common_insert_length(csize, buf, str, length, - pos); -} - -/** - * @brief Append a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to append to. - * @param c The char to append. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf. If it can not insert it, - * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. - */ -Eina_Bool -eina_strbuf_common_append_char(size_t csize, Eina_Strbuf * buf, - const void *c) -{ - - if (EINA_UNLIKELY - (!_eina_strbuf_common_grow(csize, buf, buf->len + 1))) - return EINA_FALSE; - - memcpy(buf->buf + ((buf->len)++ * csize), c, csize); - memset(buf->buf + (buf->len * csize), 0, csize); - return EINA_TRUE; -} - -/** - * @brief Insert a character to a string buffer, reallocating as - * necessary. - * - * @param buf The string buffer to insert to. - * @param c The char to insert. - * @param pos The position to insert the char. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function inserts @p c to @p buf at position @p pos. If @p buf - * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is - * returned. - */ -Eina_Bool -eina_strbuf_common_insert_char(size_t csize, - Eina_Strbuf * buf, - const void *c, size_t pos) -{ - - if (pos >= buf->len) - return eina_strbuf_common_append_char(csize, buf, c); - - return _eina_strbuf_common_insert_length(csize, buf, c, 1, pos); -} - -/** - * @brief Remove a slice of the given string buffer. - * - * @param buf The string buffer to remove a slice. - * @param start The initial (inclusive) slice position to start - * removing, in bytes. - * @param end The final (non-inclusive) slice position to finish - * removing, in bytes. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function removes a slice of @p buf, starting at @p start - * (inclusive) and ending at @p end (non-inclusive). Both values are - * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. - */ -Eina_Bool -eina_strbuf_common_remove(size_t csize, - Eina_Strbuf * buf, size_t start, size_t end) -{ - size_t remove_len, tail_len; - - if (end >= buf->len) - end = buf->len; - - if (end <= start) - return EINA_TRUE; - - remove_len = end - start; - if (remove_len == buf->len) { - free(buf->buf); - return _eina_strbuf_common_init(csize, buf); - } - - tail_len = buf->len - end + 1; /* includes '\0' */ - memmove(buf->buf + (start * csize), - buf->buf + (end * csize), tail_len * csize); - buf->len -= remove_len; - return _eina_strbuf_common_resize(csize, buf, buf->len); -} - -/** - * @brief Retrieve a pointer to the contents of a string buffer - * - * @param buf The string buffer. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. The returned - * value must not be modified and will no longer be valid if @p buf is - * modified. In other words, any eina_strbuf_common_append() or similar will - * make that pointer invalid. - * - * @see eina_strbuf_common_string_steal() - */ -const void *eina_strbuf_common_string_get(const Eina_Strbuf * buf) -{ - return buf->buf; -} - -/** - * @brief Steal the contents of a string buffer. - * - * @param buf The string buffer to steal. - * @return The current string in the string buffer. - * - * This function returns the string contained in @p buf. @p buf is - * then initialized and does not own the returned string anymore. The - * caller must release the memory of the returned string by calling - * free(). - * - * @see eina_strbuf_common_string_get() - */ -void *eina_strbuf_common_string_steal(size_t csize, Eina_Strbuf * buf) -{ - void *ret; - - ret = buf->buf; - // TODO: Check return value and do something clever - _eina_strbuf_common_init(csize, buf); - return ret; -} - -/** - * @brief Free the contents of a string buffer but not the buffer. - * - * @param buf The string buffer to free the string of. - * - * This function frees the string contained in @p buf without freeing - * @p buf. - */ -void eina_strbuf_common_string_free(size_t csize, Eina_Strbuf * buf) -{ - free(buf->buf); - _eina_strbuf_common_init(csize, buf); -} - -/** - * @brief Retrieve the length of the string buffer content. - * - * @param buf The string buffer. - * @return The current length of the string, in bytes. - * - * This function returns the length of @p buf. - */ -size_t eina_strbuf_common_length_get(const Eina_Strbuf * buf) -{ - return buf->len; -} - -/** - * @addtogroup Eina_String_Buffer_Group String Buffer - * - * @brief These functions provide string buffers management. - * - * The String Buffer data type is designed to be a mutable string, - * allowing to append, prepend or insert a string to a buffer. - * - * @{ - */ - - -/** - * @cond LOCAL - */ - -/*FIXME: Implementing them here is a hack! */ - -#ifdef _STRBUF_CSIZE -#undef _STRBUF_CSIZE -#endif - -#ifdef _STRBUF_MAGIC -#undef _STRBUF_MAGIC -#endif - -#ifdef _STRBUF_MAGIC_STR -#undef _STRBUF_MAGIC_STR -#endif - -#define _STRBUF_CSIZE 1 -#define _STRBUF_MAGIC EINA_MAGIC_STRBUF -#define _STRBUF_MAGIC_STR __STRBUF_STR_MAGIC_STR -static const char __STRBUF_STR_MAGIC_STR[] = "Eina Strbuf"; - - -/** - * @endcond - */ - - -/** - * @brief Replace the n-th string with an other string. - * - * @param buf The string buffer to work with. - * @param str The string to replace. - * @param with The replaceing string. - * @param n The number of the fitting string. - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function replaces the n-th occurrence of @p str in @p buf with - * @p with. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. - */ -EAPI Eina_Bool -eina_strbuf_replace(Eina_Strbuf * buf, - const char *str, const char *with, unsigned int n) -{ - size_t len1, len2; - char *spos; - size_t pos; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(with, EINA_FALSE); - EINA_MAGIC_CHECK_STRBUF(buf, 0); - - if (n == 0) - return EINA_FALSE; - - spos = buf->buf; - while (n--) { - spos = strstr(spos, str); - if (!spos || *spos == '\0') - return EINA_FALSE; - - if (n) - spos++; - } - - pos = spos - (const char *) buf->buf; - len1 = strlen(str); - len2 = strlen(with); - if (len1 != len2) { - /* resize the buffer if necessary */ - if (EINA_UNLIKELY - (!_eina_strbuf_common_grow - (_STRBUF_CSIZE, buf, buf->len - len1 + len2))) { - return EINA_FALSE; /* move the existing text */ - - } - - memmove(buf->buf + pos + len2, buf->buf + pos + len1, - buf->len - pos - len1); - } - - /* and now insert the given string */ - memcpy(buf->buf + pos, with, len2); - buf->len += len2 - len1; - memset((char *) buf->buf + buf->len, 0, 1); - - return EINA_TRUE; -} - -/** - * @brief Replace all strings with an other string. - - * @param buf the string buffer to work with. - * @param str The string to replace. - * @param with The replaceing string. - * @return How often the string was replaced. - * - * This function replaces all the occurrences of @p str in @ buf with - * the string @p with. This function returns the number of times @p str - * has been replaced. On failure, it returns 0. - */ -EAPI int -eina_strbuf_replace_all(Eina_Strbuf * buf, const char *str, - const char *with) -{ - size_t len1, len2, len; - char *tmp_buf = NULL; - char *spos; - size_t pos, start; - size_t pos_tmp, start_tmp; - int n = 0; - - EINA_SAFETY_ON_NULL_RETURN_VAL(str, 0); - EINA_SAFETY_ON_NULL_RETURN_VAL(with, 0); - EINA_MAGIC_CHECK_STRBUF(buf, 0); - - spos = strstr(buf->buf, str); - if (!spos || *spos == '\0') - return 0; - - len1 = strlen(str); - len2 = strlen(with); - - /* if the size of the two string is equal, it is fairly easy to replace them - * we don't need to resize the buffer or doing other calculations */ - if (len1 == len2) { - while (spos) { - memcpy(spos, with, len2); - spos = strstr(spos + len2, str); - n++; - } - return n; - } - - pos = pos_tmp = spos - (const char *) buf->buf; - tmp_buf = buf->buf; - buf->buf = malloc(buf->size); - if (EINA_UNLIKELY(!buf->buf)) { - buf->buf = tmp_buf; - return 0; - } - - start = start_tmp = 0; - len = buf->len; - - while (spos) { - n++; - len = (len + len2) - len1; - /* resize the buffer if necessary */ - if (EINA_UNLIKELY - (!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf, len))) { - /* we have to stop replacing here, because we haven't enough - * memory to go on */ - len = (len + len1) - len2; - break; - } - - /* copy the untouched text */ - memcpy(buf->buf + start, tmp_buf + start_tmp, pos - start); - /* copy the new string */ - memcpy(buf->buf + pos, with, len2); - - /* calculate the next positions */ - start_tmp = pos_tmp + len1; - start = pos + len2; - spos = strstr(tmp_buf + start_tmp, str); - /* this calculations don't make sense if spos == NULL, but the - * calculated values won't be used, because the loop will stop - * then */ - pos_tmp = spos - tmp_buf; - pos = start + pos_tmp - start_tmp; - } - /* and now copy the rest of the text */ - memcpy(buf->buf + start, tmp_buf + start_tmp, len - start); - buf->len = len; - memset((char *) buf->buf + buf->len, 0, 1); - - free(tmp_buf); - - return n; -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_strbuf_common.h b/tests/suite/ecore/src/lib/eina_strbuf_common.h deleted file mode 100644 index 0c38e639b1..0000000000 --- a/tests/suite/ecore/src/lib/eina_strbuf_common.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef EINA_STRBUF_COMMON_H -#define EINA_STRBUF_COMMON_H - -#include <stdlib.h> - -#include "eina_private.h" -#include "eina_magic.h" -#include "eina_strbuf.h" - -struct _Eina_Strbuf { - void *buf; - size_t len; - size_t size; - size_t step; - - EINA_MAGIC}; - -#define EINA_MAGIC_CHECK_STRBUF(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK((d), _STRBUF_MAGIC)) \ - { \ - EINA_MAGIC_FAIL((d), _STRBUF_MAGIC); \ - return __VA_ARGS__; \ - } \ - } while (0) - -Eina_Bool eina_strbuf_common_init(void); - -Eina_Bool eina_strbuf_common_shutdown(void); -Eina_Strbuf *eina_strbuf_common_new(size_t csize); -void eina_strbuf_common_free(Eina_Strbuf * buf); -void eina_strbuf_common_reset(size_t csize, Eina_Strbuf * buf); -Eina_Bool -eina_strbuf_common_append(size_t csize, - Eina_Strbuf * buf, const void *str, size_t len); -Eina_Bool -eina_strbuf_common_append_escaped(size_t csize, - Eina_Strbuf * buf, const void *str); -Eina_Bool -eina_strbuf_common_append_n(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t len, size_t maxlen); -Eina_Bool -eina_strbuf_common_append_length(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t length); -Eina_Bool -eina_strbuf_common_insert(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t len, size_t pos); -Eina_Bool -eina_strbuf_common_insert_escaped(size_t csize, - Eina_Strbuf * buf, - const void *str, size_t len, size_t pos); -Eina_Bool -eina_strbuf_common_insert_n(size_t csize, - Eina_Strbuf * buf, - const void *str, - size_t len, size_t maxlen, size_t pos); -Eina_Bool -eina_strbuf_common_insert_length(size_t csize, - Eina_Strbuf * buf, - const void *str, - size_t length, size_t pos); -Eina_Bool -eina_strbuf_common_append_char(size_t csize, Eina_Strbuf * buf, - const void *c); -Eina_Bool eina_strbuf_common_insert_char(size_t csize, Eina_Strbuf * buf, - const void *c, size_t pos); -Eina_Bool eina_strbuf_common_remove(size_t csize, Eina_Strbuf * buf, - size_t start, size_t end); -const void *eina_strbuf_common_string_get(const Eina_Strbuf * buf); -void *eina_strbuf_common_string_steal(size_t csize, Eina_Strbuf * buf); -void eina_strbuf_common_string_free(size_t csize, Eina_Strbuf * buf); -size_t eina_strbuf_common_length_get(const Eina_Strbuf * buf); - -Eina_Bool -_eina_strbuf_common_grow(size_t csize, Eina_Strbuf * buf, size_t size); -/** - * @} - */ - -#endif diff --git a/tests/suite/ecore/src/lib/eina_strbuf_template_c.x b/tests/suite/ecore/src/lib/eina_strbuf_template_c.x deleted file mode 100644 index 2f3aeae4b4..0000000000 --- a/tests/suite/ecore/src/lib/eina_strbuf_template_c.x +++ /dev/null @@ -1,216 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ - -/* This file should be included from files implementing strbuf. The including file - * should define the following macros: - * _STRBUF_DATA_TYPE - * _STRBUF_CSIZE - * _STRBUF_STRUCT_NAME - * _STRBUF_STRLEN_FUNC(x) - * _STRBUF_STRESCAPE_FUNC(x) - * _STRBUF_STRSTR_FUNC(x, y) - * _STRBUF_MAGIC - * _STRBUF_MAGIC_STR - * See how it's done in eina_ustrbuf.c and eina_strbuf.c. This just makes things - * a lot easier since those are essentially the same just with different sizes. - */ - -/*============================================================================* - * Local * - *============================================================================*/ - - -/*============================================================================* - * Global * - *============================================================================*/ - -/** - * @internal - * @brief Initialize the strbuf module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the strbuf module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool -_FUNC_EXPAND(init)(void) -{ - eina_magic_string_static_set(_STRBUF_MAGIC, _STRBUF_MAGIC_STR); - return eina_strbuf_common_init(); -} - -/** - * @internal - * @brief Shut down the strbuf module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the strbuf module set up by - * eina_ustrbuf_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool -_FUNC_EXPAND(shutdown)(void) -{ - return eina_strbuf_common_shutdown(); -} - -/*============================================================================* - * API * - *============================================================================*/ - -EAPI _STRBUF_STRUCT_NAME * -_FUNC_EXPAND(new)(void) -{ - _STRBUF_STRUCT_NAME *buf = eina_strbuf_common_new(_STRBUF_CSIZE); - EINA_MAGIC_SET(buf, _STRBUF_MAGIC); - return buf; -} - -EAPI void -_FUNC_EXPAND(free)(_STRBUF_STRUCT_NAME *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf); - EINA_MAGIC_SET(buf, EINA_MAGIC_NONE); - eina_strbuf_common_free(buf); -} - -EAPI void -_FUNC_EXPAND(reset)(_STRBUF_STRUCT_NAME *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf); - eina_strbuf_common_reset(_STRBUF_CSIZE, buf); -} - -EAPI Eina_Bool -_FUNC_EXPAND(append)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_append(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str)); -} - -EAPI Eina_Bool -_FUNC_EXPAND(append_escaped)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str) -{ - _STRBUF_DATA_TYPE *esc; - Eina_Bool ret; - - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - esc = _STRBUF_STRESCAPE_FUNC(str); - if (!esc) { - return _FUNC_EXPAND(append)(buf, str); - } - ret = _FUNC_EXPAND(append)(buf, esc); - if (esc) - free(esc); - - return ret; -} - -EAPI Eina_Bool -_FUNC_EXPAND(append_n)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t maxlen) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_append_n(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), maxlen); -} - -EAPI Eina_Bool -_FUNC_EXPAND(append_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t length) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_append_length(_STRBUF_CSIZE, buf, (const void *) str, length); -} - -EAPI Eina_Bool -_FUNC_EXPAND(insert)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t pos) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_insert(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), pos); -} - -EAPI Eina_Bool -_FUNC_EXPAND(insert_escaped)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t pos) -{ - _STRBUF_DATA_TYPE *esc; - Eina_Bool ret; - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - - esc = _STRBUF_STRESCAPE_FUNC(str); - if (!esc) { - return _FUNC_EXPAND(insert)(buf, str, pos); - } - ret = _FUNC_EXPAND(insert)(buf, esc, pos); - if (esc) - free(esc); - - return ret; -} - -EAPI Eina_Bool -_FUNC_EXPAND(insert_n)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t maxlen, size_t pos) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_insert_n(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), maxlen, pos); -} - -EAPI Eina_Bool -_FUNC_EXPAND(insert_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t length, size_t pos) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_insert_length(_STRBUF_CSIZE, buf, (const void *) str, length, pos); -} - -EAPI Eina_Bool -_FUNC_EXPAND(append_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_append_char(_STRBUF_CSIZE, buf, (const void *) &c); -} - -EAPI Eina_Bool -_FUNC_EXPAND(insert_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c, size_t pos) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_insert_char(_STRBUF_CSIZE, buf, (const void *) &c, pos); -} - -EAPI Eina_Bool -_FUNC_EXPAND(remove)(_STRBUF_STRUCT_NAME *buf, size_t start, size_t end) -{ - EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); - return eina_strbuf_common_remove(_STRBUF_CSIZE, buf, start, end); -} - -EAPI const _STRBUF_DATA_TYPE * -_FUNC_EXPAND(string_get)(const _STRBUF_STRUCT_NAME *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf, NULL); - return (const _STRBUF_DATA_TYPE *) eina_strbuf_common_string_get(buf); -} - -EAPI _STRBUF_DATA_TYPE * -_FUNC_EXPAND(string_steal)(_STRBUF_STRUCT_NAME *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf, NULL); - return (_STRBUF_DATA_TYPE *) eina_strbuf_common_string_steal(_STRBUF_CSIZE, buf); -} - - -EAPI void -_FUNC_EXPAND(string_free)(_STRBUF_STRUCT_NAME *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf); - eina_strbuf_common_string_free(_STRBUF_CSIZE, buf); -} - -EAPI size_t -_FUNC_EXPAND(length_get)(const _STRBUF_STRUCT_NAME *buf) -{ - EINA_MAGIC_CHECK_STRBUF(buf, 0); - return eina_strbuf_common_length_get(buf); -} diff --git a/tests/suite/ecore/src/lib/eina_stringshare.c b/tests/suite/ecore/src/lib/eina_stringshare.c deleted file mode 100644 index 5251929e4f..0000000000 --- a/tests/suite/ecore/src/lib/eina_stringshare.c +++ /dev/null @@ -1,948 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2010 - * Carsten Haitzler, - * Jorge Luis Zapata Muga, - * Cedric Bail, - * Gustavo Sverzut Barbieri - * Tom Hacohen - * 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 <https://www.gnu.org/licenses/>. - */ - -/** - * @page tutorial_stringshare_page Stringshare Tutorial - * - * to be written... - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _GNU_SOURCE - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#elif defined __GNUC__ -#define alloca __builtin_alloca -#elif defined _AIX -#define alloca __alloca -#elif defined _MSC_VER -#include <malloc.h> -#define alloca _alloca -#else -#include <stddef.h> -#ifdef __cplusplus -extern "C" -#endif -void *alloca(size_t); -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef EFL_HAVE_POSIX_THREADS -#include <pthread.h> -#endif - -#ifdef HAVE_EVIL -#include <Evil.h> -#endif - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_hash.h" -#include "eina_rbtree.h" -#include "eina_error.h" -#include "eina_log.h" -#include "eina_stringshare.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" -#include "eina_share_common.h" - -/* The actual share */ -static Eina_Share *stringshare_share; -static const char EINA_MAGIC_STRINGSHARE_NODE_STR[] = - "Eina Stringshare Node"; - -#ifdef EFL_HAVE_THREADS -extern Eina_Bool _share_common_threads_activated; - -#ifdef EFL_HAVE_POSIX_THREADS -static pthread_mutex_t _mutex_small = PTHREAD_MUTEX_INITIALIZER; -#define STRINGSHARE_LOCK_SMALL() if(_share_common_threads_activated) \ - pthread_mutex_lock(&_mutex_small) -#define STRINGSHARE_UNLOCK_SMALL() if(_share_common_threads_activated) \ - pthread_mutex_unlock(&_mutex_small) -#else /* EFL_HAVE_WIN32_THREADS */ -static HANDLE _mutex_small = NULL; -#define STRINGSHARE_LOCK_SMALL() if(_share_common_threads_activated) \ - WaitForSingleObject(_mutex_small, INFINITE) -#define STRINGSHARE_UNLOCK_SMALL() if(_share_common_threads_activated) \ - ReleaseMutex(_mutex_small) - -#endif /* EFL_HAVE_WIN32_THREADS */ -#else /* EFL_HAVE_THREADS */ -#define STRINGSHARE_LOCK_SMALL() do {} while (0) -#define STRINGSHARE_UNLOCK_SMALL() do {} while (0) -#endif - -/* Stringshare optimizations */ -static const unsigned char _eina_stringshare_single[512] = { - 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, - 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, - 16, 0, 17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24, 0, 25, - 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, - 31, 0, 32, 0, 33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40, - 0, 41, 0, 42, 0, 43, 0, 44, 0, 45, 0, - 46, 0, 47, 0, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, - 0, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, - 61, 0, 62, 0, 63, 0, 64, 0, 65, 0, 66, 0, 67, 0, 68, 0, 69, 0, 70, - 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0, - 76, 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 83, 0, 84, 0, 85, - 0, 86, 0, 87, 0, 88, 0, 89, 0, 90, 0, - 91, 0, 92, 0, 93, 0, 94, 0, 95, 0, 96, 0, 97, 0, 98, 0, 99, 0, 100, - 0, 101, 0, 102, 0, 103, 0, 104, 0, - 105, 0, - 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, - 114, 0, 115, 0, 116, 0, 117, 0, 118, - 0, 119, 0, 120, 0, - 121, 0, 122, 0, 123, 0, 124, 0, 125, 0, 126, 0, 127, 0, 128, 0, - 129, 0, 130, 0, 131, 0, 132, 0, 133, - 0, 134, 0, 135, 0, - 136, 0, 137, 0, 138, 0, 139, 0, 140, 0, 141, 0, 142, 0, 143, 0, - 144, 0, 145, 0, 146, 0, 147, 0, 148, - 0, 149, 0, 150, 0, - 151, 0, 152, 0, 153, 0, 154, 0, 155, 0, 156, 0, 157, 0, 158, 0, - 159, 0, 160, 0, 161, 0, 162, 0, 163, - 0, 164, 0, 165, 0, - 166, 0, 167, 0, 168, 0, 169, 0, 170, 0, 171, 0, 172, 0, 173, 0, - 174, 0, 175, 0, 176, 0, 177, 0, 178, - 0, 179, 0, 180, 0, - 181, 0, 182, 0, 183, 0, 184, 0, 185, 0, 186, 0, 187, 0, 188, 0, - 189, 0, 190, 0, 191, 0, 192, 0, 193, - 0, 194, 0, 195, 0, - 196, 0, 197, 0, 198, 0, 199, 0, 200, 0, 201, 0, 202, 0, 203, 0, - 204, 0, 205, 0, 206, 0, 207, 0, 208, - 0, 209, 0, 210, 0, - 211, 0, 212, 0, 213, 0, 214, 0, 215, 0, 216, 0, 217, 0, 218, 0, - 219, 0, 220, 0, 221, 0, 222, 0, 223, - 0, 224, 0, 225, 0, - 226, 0, 227, 0, 228, 0, 229, 0, 230, 0, 231, 0, 232, 0, 233, 0, - 234, 0, 235, 0, 236, 0, 237, 0, 238, - 0, 239, 0, 240, 0, - 241, 0, 242, 0, 243, 0, 244, 0, 245, 0, 246, 0, 247, 0, 248, 0, - 249, 0, 250, 0, 251, 0, 252, 0, 253, - 0, 254, 0, 255, 0 -}; - -typedef struct _Eina_Stringshare_Small Eina_Stringshare_Small; -typedef struct _Eina_Stringshare_Small_Bucket - Eina_Stringshare_Small_Bucket; - -struct _Eina_Stringshare_Small_Bucket { - /* separate arrays for faster lookups */ - const char **strings; - unsigned char *lengths; - unsigned short *references; - int count; - int size; -}; - -struct _Eina_Stringshare_Small { - Eina_Stringshare_Small_Bucket *buckets[256]; -}; - -#define EINA_STRINGSHARE_SMALL_BUCKET_STEP 8 -static Eina_Stringshare_Small _eina_small_share; - -static inline int -_eina_stringshare_small_cmp(const Eina_Stringshare_Small_Bucket * bucket, - int i, const char *pstr, unsigned char plength) -{ - /* pstr and plength are from second char and on, since the first is - * always the same. - * - * First string being always the same, size being between 2 and 3 - * characters (there is a check for special case length==1 and then - * small stringshare is applied to strings < 4), we just need to - * compare 2 characters of both strings. - */ - const unsigned char cur_plength = bucket->lengths[i] - 1; - const char *cur_pstr; - - if (cur_plength > plength) - return 1; - else if (cur_plength < plength) - return -1; - - cur_pstr = bucket->strings[i] + 1; - - if (cur_pstr[0] > pstr[0]) - return 1; - else if (cur_pstr[0] < pstr[0]) - return -1; - - if (plength == 1) - return 0; - - if (cur_pstr[1] > pstr[1]) - return 1; - else if (cur_pstr[1] < pstr[1]) - return -1; - - return 0; -} - -static const char *_eina_stringshare_small_bucket_find(const - Eina_Stringshare_Small_Bucket - * bucket, - const char *str, - unsigned char - length, int *idx) -{ - const char *pstr = str + 1; /* skip first letter, it's always the same */ - unsigned char plength = length - 1; - int i, low, high; - - if (bucket->count == 0) { - *idx = 0; - return NULL; - } - - low = 0; - high = bucket->count; - - while (low < high) { - int r; - - i = (low + high - 1) / 2; - - r = _eina_stringshare_small_cmp(bucket, i, pstr, plength); - if (r > 0) - high = i; - else if (r < 0) - low = i + 1; - else { - *idx = i; - return bucket->strings[i]; - } - } - - *idx = low; - return NULL; -} - -static Eina_Bool -_eina_stringshare_small_bucket_resize(Eina_Stringshare_Small_Bucket * - bucket, int size) -{ - void *tmp; - - tmp = - realloc((void *) bucket->strings, - size * sizeof(bucket->strings[0])); - if (!tmp) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return 0; - } - - bucket->strings = tmp; - - tmp = realloc(bucket->lengths, size * sizeof(bucket->lengths[0])); - if (!tmp) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return 0; - } - - bucket->lengths = tmp; - - tmp = - realloc(bucket->references, - size * sizeof(bucket->references[0])); - if (!tmp) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return 0; - } - - bucket->references = tmp; - - bucket->size = size; - return 1; -} - -static const char - *_eina_stringshare_small_bucket_insert_at(Eina_Stringshare_Small_Bucket - ** p_bucket, const char *str, - unsigned char length, - int idx) -{ - Eina_Stringshare_Small_Bucket *bucket = *p_bucket; - int todo, off; - char *snew; - - if (!bucket) { - *p_bucket = bucket = calloc(1, sizeof(*bucket)); - if (!bucket) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - } - - if (bucket->count + 1 >= bucket->size) { - int size = - bucket->size + EINA_STRINGSHARE_SMALL_BUCKET_STEP; - if (!_eina_stringshare_small_bucket_resize(bucket, size)) - return NULL; - } - - snew = malloc(length + 1); - if (!snew) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - memcpy(snew, str, length); - snew[length] = '\0'; - - off = idx + 1; - todo = bucket->count - idx; - if (todo > 0) { - memmove((void *) (bucket->strings + off), - bucket->strings + idx, - todo * sizeof(bucket->strings[0])); - memmove(bucket->lengths + off, bucket->lengths + idx, - todo * sizeof(bucket->lengths[0])); - memmove(bucket->references + off, bucket->references + idx, - todo * sizeof(bucket->references[0])); - } - - bucket->strings[idx] = snew; - bucket->lengths[idx] = length; - bucket->references[idx] = 1; - bucket->count++; - - return snew; -} - -static void -_eina_stringshare_small_bucket_remove_at(Eina_Stringshare_Small_Bucket ** - p_bucket, int idx) -{ - Eina_Stringshare_Small_Bucket *bucket = *p_bucket; - int todo, off; - - if (bucket->references[idx] > 1) { - bucket->references[idx]--; - return; - } - - free((char *) bucket->strings[idx]); - - if (bucket->count == 1) { - free((void *) bucket->strings); - free(bucket->lengths); - free(bucket->references); - free(bucket); - *p_bucket = NULL; - return; - } - - bucket->count--; - if (idx == bucket->count) - goto end; - - off = idx + 1; - todo = bucket->count - idx; - - memmove((void *) (bucket->strings + idx), bucket->strings + off, - todo * sizeof(bucket->strings[0])); - memmove(bucket->lengths + idx, bucket->lengths + off, - todo * sizeof(bucket->lengths[0])); - memmove(bucket->references + idx, bucket->references + off, - todo * sizeof(bucket->references[0])); - - end: - if (bucket->count + EINA_STRINGSHARE_SMALL_BUCKET_STEP < - bucket->size) { - int size = - bucket->size - EINA_STRINGSHARE_SMALL_BUCKET_STEP; - _eina_stringshare_small_bucket_resize(bucket, size); - } -} - -static const char *_eina_stringshare_small_add(const char *str, - unsigned char length) -{ - Eina_Stringshare_Small_Bucket **bucket; - int i; - - bucket = _eina_small_share.buckets + (unsigned char) str[0]; - if (!*bucket) - i = 0; - else { - const char *ret; - ret = - _eina_stringshare_small_bucket_find(*bucket, str, - length, &i); - if (ret) { - (*bucket)->references[i]++; - return ret; - } - } - - return _eina_stringshare_small_bucket_insert_at(bucket, str, - length, i); -} - -static void -_eina_stringshare_small_del(const char *str, unsigned char length) -{ - Eina_Stringshare_Small_Bucket **bucket; - const char *ret; - int i; - - bucket = _eina_small_share.buckets + (unsigned char) str[0]; - if (!*bucket) - goto error; - - ret = - _eina_stringshare_small_bucket_find(*bucket, str, length, &i); - if (!ret) - goto error; - - _eina_stringshare_small_bucket_remove_at(bucket, i); - return; - - error: - CRITICAL("EEEK trying to del non-shared stringshare \"%s\"", str); -} - -static void _eina_stringshare_small_init(void) -{ - memset(&_eina_small_share, 0, sizeof(_eina_small_share)); -} - -static void _eina_stringshare_small_shutdown(void) -{ - Eina_Stringshare_Small_Bucket **p_bucket, **p_bucket_end; - - p_bucket = _eina_small_share.buckets; - p_bucket_end = p_bucket + 256; - - for (; p_bucket < p_bucket_end; p_bucket++) { - Eina_Stringshare_Small_Bucket *bucket = *p_bucket; - char **s, **s_end; - - if (!bucket) - continue; - - s = (char **) bucket->strings; - s_end = s + bucket->count; - for (; s < s_end; s++) - free(*s); - - free((void *) bucket->strings); - free(bucket->lengths); - free(bucket->references); - free(bucket); - *p_bucket = NULL; - } -} - -static void -_eina_stringshare_small_bucket_dump(Eina_Stringshare_Small_Bucket * bucket, - struct dumpinfo *di) -{ - const char **s = bucket->strings; - unsigned char *l = bucket->lengths; - unsigned short *r = bucket->references; - int i; - - di->used += sizeof(*bucket); - di->used += bucket->count * sizeof(*s); - di->used += bucket->count * sizeof(*l); - di->used += bucket->count * sizeof(*r); - di->unique += bucket->count; - - for (i = 0; i < bucket->count; i++, s++, l++, r++) { - int dups; -#ifdef _WIN32 - printf("DDD: %5hu %5hu '%s'\n", *l, *r, *s); -#else - printf("DDD: %5hhu %5hu '%s'\n", *l, *r, *s); -#endif - - dups = (*r - 1); - - di->used += *l; - di->saved += *l * dups; - di->dups += dups; - } -} - -static void _eina_stringshare_small_dump(struct dumpinfo *di) -{ - Eina_Stringshare_Small_Bucket **p_bucket, **p_bucket_end; - - p_bucket = _eina_small_share.buckets; - p_bucket_end = p_bucket + 256; - - for (; p_bucket < p_bucket_end; p_bucket++) { - Eina_Stringshare_Small_Bucket *bucket = *p_bucket; - - if (!bucket) - continue; - - _eina_stringshare_small_bucket_dump(bucket, di); - } -} - - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the share_common module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_stringshare_init(void) -{ - Eina_Bool ret; - ret = eina_share_common_init(&stringshare_share, - EINA_MAGIC_STRINGSHARE_NODE, - EINA_MAGIC_STRINGSHARE_NODE_STR); - if (ret) - _eina_stringshare_small_init(); - - return ret; -} - -/** - * @internal - * @brief Shut down the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the share_common module set up by - * eina_share_common_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_stringshare_shutdown(void) -{ - Eina_Bool ret; - _eina_stringshare_small_shutdown(); - ret = eina_share_common_shutdown(&stringshare_share); - return ret; -} - -/*============================================================================* -* API * -*============================================================================*/ - -/** - * @addtogroup Eina_Stringshare_Group Stringshare - * - * 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. - * - * For more information, you can look at the @ref tutorial_stringshare_page. - * - * @{ - */ - -/** - * @brief Note that the given string has lost an instance. - * - * @param str string The given string. - * - * This function decreases the reference counter associated to @p str - * if it exists. If that counter reaches 0, the memory associated to - * @p str is freed. If @p str is NULL, the function returns - * immediately. - * - * Note that if the given pointer is not shared or NULL, bad things - * will happen, likely a segmentation fault. - */ -EAPI void eina_stringshare_del(const char *str) -{ - int slen; - DBG("str=%p (%s)", str, str ? str : ""); - if (!str) - return; - - /* special cases */ - if (str[0] == '\0') - slen = 0; - else if (str[1] == '\0') - slen = 1; - else if (str[2] == '\0') - slen = 2; - else if (str[3] == '\0') - slen = 3; - else - slen = 4; /* handled later */ - - if (slen < 2) - return; - else if (slen < 4) { - eina_share_common_population_del(stringshare_share, slen); - STRINGSHARE_LOCK_SMALL(); - _eina_stringshare_small_del(str, slen); - STRINGSHARE_UNLOCK_SMALL(); - return; - } - - eina_share_common_del(stringshare_share, str); -} - -/** - * @brief Retrieve an instance of a string for use in a program. - * - * @param str The string to retrieve an instance of. - * @param slen The string size (<= strlen(str)). - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p str. If @p str is - * @c NULL, then @c NULL is returned. If @p str is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the strings to be searched and a duplicated string - * of @p str is returned. - * - * This function does not check string size, but uses the - * exact given size. This can be used to share_common part of a larger - * buffer or substring. - * - * @see eina_share_common_add() - */ -EAPI const char *eina_stringshare_add_length(const char *str, - unsigned int slen) -{ - DBG("str=%p (%.*s), slen=%u", str, slen, str ? str : "", slen); - - if (slen <= 0) - return ""; - else if (slen == 1) - return (const char *) _eina_stringshare_single + - ((*str) << 1); - else if (slen < 4) { - const char *s; - - STRINGSHARE_LOCK_SMALL(); - s = _eina_stringshare_small_add(str, slen); - STRINGSHARE_UNLOCK_SMALL(); - return s; - } - - return eina_share_common_add_length(stringshare_share, str, slen * - sizeof(char), sizeof(char)); -} - -/** - * @brief Retrieve an instance of a string for use in a program. - * - * @param str The NULL terminated string to retrieve an instance of. - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p str. If @p str is - * @c NULL, then @c NULL is returned. If @p str is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the strings to be searched and a duplicated string - * of @p str is returned. - * - * The string @p str must be NULL terminated ('@\0') and its full - * length will be used. To use part of the string or non-null - * terminated, use eina_stringshare_add_length() instead. - * - * @see eina_stringshare_add_length() - */ -EAPI const char *eina_stringshare_add(const char *str) -{ - int slen; - if (!str) - return NULL; - - if (str[0] == '\0') - slen = 0; - else if (str[1] == '\0') - slen = 1; - else if (str[2] == '\0') - slen = 2; - else if (str[3] == '\0') - slen = 3; - else - slen = 3 + (int) strlen(str + 3); - - return eina_stringshare_add_length(str, slen); -} - -/** - * @brief Retrieve an instance of a string for use in a program - * from a format string. - * - * @param fmt The NULL terminated format string to retrieve an instance of. - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p fmt. If @p fmt is - * @c NULL, then @c NULL is returned. If @p fmt is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the strings to be searched and a duplicated string - * is returned. - * - * The format string @p fmt must be NULL terminated ('@\0') and its full - * length will be used. To use part of the format string or non-null - * terminated, use eina_stringshare_nprintf() instead. - * - * @see eina_stringshare_nprintf() - */ -EAPI const char *eina_stringshare_printf(const char *fmt, ...) -{ - va_list args; - char *tmp; - const char *ret; - int len; - - if (!fmt) - return NULL; - - va_start(args, fmt); - len = vasprintf(&tmp, fmt, args); - va_end(args); - - if (len < 1) - return NULL; - - ret = eina_stringshare_add_length(tmp, len); - free(tmp); - - return ret; -} - -/** - * @brief Retrieve an instance of a string for use in a program - * from a format string. - * - * @param fmt The NULL terminated format string to retrieve an instance of. - * @param args The va_args for @p fmt - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p fmt with @p args. If @p fmt is - * @c NULL, then @c NULL is returned. If @p fmt with @p args is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the strings to be searched and a duplicated string - * is returned. - * - * The format string @p fmt must be NULL terminated ('@\0') and its full - * length will be used. To use part of the format string or non-null - * terminated, use eina_stringshare_nprintf() instead. - * - * @see eina_stringshare_nprintf() - */ -EAPI const char *eina_stringshare_vprintf(const char *fmt, va_list args) -{ - char *tmp; - const char *ret; - int len; - - if (!fmt) - return NULL; - - len = vasprintf(&tmp, fmt, args); - - if (len < 1) - return NULL; - - ret = eina_stringshare_add_length(tmp, len); - free(tmp); - - return ret; -} - -/** - * @brief Retrieve an instance of a string for use in a program - * from a format string with size limitation. - * @param len The length of the format string to use - * @param fmt The format string to retrieve an instance of. - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p fmt limited by @p len. If @p fmt is - * @c NULL or @p len is < 1, then @c NULL is returned. If the resulting string - * is already stored, it is returned and its reference counter is increased. Otherwise - * it is added to the strings to be searched and a duplicated string - * is returned. - * - * @p len length of the format string will be used. To use the - * entire format string, use eina_stringshare_printf() instead. - * - * @see eina_stringshare_printf() - */ -EAPI const char *eina_stringshare_nprintf(unsigned int len, - const char *fmt, ...) -{ - va_list args; - char *tmp; - int size; - - if (!fmt) - return NULL; - - if (len < 1) - return NULL; - - tmp = alloca(sizeof(char) * len + 1); - - va_start(args, fmt); - size = vsnprintf(tmp, len, fmt, args); - va_end(args); - - if (size < 1) - return NULL; - - return eina_stringshare_add_length(tmp, len); -} - -/** - * Increment references of the given shared string. - * - * @param str The shared string. - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This is similar to eina_share_common_add(), but it's faster since it will - * avoid lookups if possible, but on the down side it requires the parameter - * to be shared before, in other words, it must be the return of a previous - * eina_share_common_add(). - * - * There is no unref since this is the work of eina_share_common_del(). - */ -EAPI const char *eina_stringshare_ref(const char *str) -{ - int slen; - DBG("str=%p (%s)", str, str ? str : ""); - - if (!str) - return eina_share_common_ref(stringshare_share, str); - - /* special cases */ - if (str[0] == '\0') - slen = 0; - else if (str[1] == '\0') - slen = 1; - else if (str[2] == '\0') - slen = 2; - else if (str[3] == '\0') - slen = 3; - else - slen = 3 + (int) strlen(str + 3); - - if (slen < 2) { - eina_share_common_population_add(stringshare_share, slen); - - return str; - } else if (slen < 4) { - const char *s; - eina_share_common_population_add(stringshare_share, slen); - - STRINGSHARE_LOCK_SMALL(); - s = _eina_stringshare_small_add(str, slen); - STRINGSHARE_UNLOCK_SMALL(); - - return s; - } - - return eina_share_common_ref(stringshare_share, str); -} - -/** - * @brief Note that the given string @b must be shared. - * - * @param str the shared string to know the length. It is safe to - * give NULL, in that case -1 is returned. - * - * This function is a cheap way to known the length of a shared - * string. Note that if the given pointer is not shared, bad - * things will happen, likely a segmentation fault. If in doubt, try - * strlen(). - */ -EAPI int eina_stringshare_strlen(const char *str) -{ - int len; - /* special cases */ - if (str[0] == '\0') - return 0; - - if (str[1] == '\0') - return 1; - - if (str[2] == '\0') - return 2; - - if (str[3] == '\0') - return 3; - - len = - eina_share_common_length(stringshare_share, - (const char *) str); - len = (len > 0) ? len / (int) sizeof(char) : -1; - return len; -} - -/** - * @brief Dump the contents of the share_common. - * - * This function dumps all strings in the share_common to stdout with a - * DDD: prefix per line and a memory usage summary. - */ -EAPI void eina_stringshare_dump(void) -{ - eina_share_common_dump(stringshare_share, - _eina_stringshare_small_dump, - sizeof(_eina_stringshare_single)); -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_tiler.c b/tests/suite/ecore/src/lib/eina_tiler.c deleted file mode 100644 index 57331b385d..0000000000 --- a/tests/suite/ecore/src/lib/eina_tiler.c +++ /dev/null @@ -1,1227 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2007-2008 Gustavo Sverzut Barbieri, Jorge Luis Zapata Muga - * - * 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 <https://www.gnu.org/licenses/>. - */ - -/* TODO - * it is possible to have more than one tiler algorithm, but for now the - * version Gustavo did is hardcoded here - * http://blog.gustavobarbieri.com.br/2007/06/03/evas-now-using-rectangle-split-and-merge/ - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> - -#include "eina_config.h" -#include "eina_private.h" -#include "eina_tiler.h" -#include "eina_error.h" - -/*============================================================================* -* Local * -*============================================================================*/ - -/* The splitter data types */ -typedef struct list_node list_node_t; -typedef struct list list_t; -typedef struct rect rect_t; -typedef struct rect_node rect_node_t; - -struct list_node { - struct list_node *next; -}; - -struct list { - struct list_node *head; - struct list_node *tail; -}; - -struct rect { - short right; - short bottom; - short left; - short top; - short width; - short height; - int area; -}; - -struct rect_node { - struct list_node _lst; - struct rect rect; -}; - -typedef struct splitter { - Eina_Bool need_merge; - list_t rects; -} splitter_t; - -typedef struct list_node_pool { - list_node_t *node; - int len; - int max; -} list_node_pool_t; - - -static const list_node_t list_node_zeroed = { NULL }; -static const list_t list_zeroed = { NULL, NULL }; -static list_node_pool_t list_node_pool = { NULL, 0, 1024 }; - - -typedef struct _Eina_Iterator_Tiler { - Eina_Iterator iterator; - const Eina_Tiler *tiler; - list_node_t *curr; - EINA_MAGIC} Eina_Iterator_Tiler; - -struct _Eina_Tiler { - struct { - int w, h; - } tile; - Eina_Rectangle area; - EINA_MAGIC splitter_t splitter; -}; - -#define EINA_MAGIC_CHECK_TILER(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_TILER)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_TILER); \ - return __VA_ARGS__; \ - } \ - } while(0) - - -#define EINA_MAGIC_CHECK_TILER_ITERATOR(d, ...) \ - do { \ - if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_TILER_ITERATOR)) \ - { \ - EINA_MAGIC_FAIL(d, EINA_MAGIC_TILER_ITERATOR); \ - return __VA_ARGS__; \ - } \ - } while(0) - -/* The Splitter algorithm */ -static inline void rect_init(rect_t * r, int x, int y, int w, int h) -{ - r->area = w * h; - - r->left = x; - r->top = y; - - r->right = x + w; - r->bottom = y + h; - - r->width = w; - r->height = h; -} - -static inline list_node_t *rect_list_node_pool_get(void) -{ - if (list_node_pool.node) { - list_node_t *node; - - node = list_node_pool.node; - list_node_pool.node = node->next; - list_node_pool.len--; - - return node; - } else - return malloc(sizeof(rect_node_t)); -} - - -static inline void rect_list_concat(list_t * rects, list_t * other) -{ - if (!other->head) - return; - - if (rects->tail) { - rects->tail->next = other->head; - rects->tail = other->tail; - } else { - rects->head = other->head; - rects->tail = other->tail; - } - - *other = list_zeroed; -} - -static inline void rect_list_append_node(list_t * rects, - list_node_t * node) -{ - if (rects->tail) { - rects->tail->next = node; - rects->tail = node; - } else { - rects->head = node; - rects->tail = node; - } -} - -static inline void rect_list_append(list_t * rects, const rect_t r) -{ - rect_node_t *rect_node; - - rect_node = (rect_node_t *) rect_list_node_pool_get(); - rect_node->rect = r; - rect_node->_lst = list_node_zeroed; - - rect_list_append_node(rects, (list_node_t *) rect_node); -} - -static inline void rect_list_append_xywh(list_t * rects, - int x, int y, int w, int h) -{ - rect_t r; - - rect_init(&r, x, y, w, h); - rect_list_append(rects, r); -} - -static inline void _calc_intra_rect_area(const rect_t a, const rect_t b, - int *width, int *height) -{ - int max_left, min_right, max_top, min_bottom; - - if (a.left < b.left) - max_left = b.left; - else - max_left = a.left; - - if (a.right < b.right) - min_right = a.right; - else - min_right = b.right; - - *width = min_right - max_left; - - if (a.top < b.top) - max_top = b.top; - else - max_top = a.top; - - if (a.bottom < b.bottom) - min_bottom = a.bottom; - else - min_bottom = b.bottom; - - *height = min_bottom - max_top; -} - -static inline void _split_strict(list_t * dirty, const rect_t current, - rect_t r) -{ - int h_1, h_2, w_1, w_2; - - h_1 = current.top - r.top; - h_2 = r.bottom - current.bottom; - w_1 = current.left - r.left; - w_2 = r.right - current.right; - - if (h_1 > 0) { - /* .--.r (b) .---.r2 - * | | | | - * .-------.cur (a) .---.r '---' - * | | | | -> | | + - * | `--' | `---' - * `-------' - */ - rect_list_append_xywh(dirty, r.left, r.top, r.width, h_1); - r.height -= h_1; - r.top = current.top; - } - - if (h_2 > 0) { - /* .-------.cur (a) - * | .---. | .---.r - * | | | | -> | | - * `-------' `---' + .---.r2 - * | | | | - * `---'r (b) `---' - */ - rect_list_append_xywh(dirty, r.left, current.bottom, - r.width, h_2); - r.height -= h_2; - } - - if (w_1 > 0) - /* (b) r .----.cur (a) - * .--|-. | .--.r2 .-.r - * | | | | -> | | + | | - * `--|-' | `--' `-' - * `----' - */ - rect_list_append_xywh(dirty, r.left, r.top, w_1, r.height); /* not necessary to keep these, r (b) will be destroyed */ - - /* r.width -= w_1; */ - /* r.left = current.left; */ - - if (w_2 > 0) - /* .----.cur (a) - * | | - * | .-|--.r (b) .-.r .--.r2 - * | | | | -> | | + | | - * | `-|--' `-' `--' - * `----' - */ - rect_list_append_xywh(dirty, current.right, r.top, w_2, r.height); /* not necessary to keep this, r (b) will be destroyed */ - - /* r.width -= w_2; */ -} - -static inline void _calc_intra_outer_rect_area(const rect_t a, - const rect_t b, - rect_t * intra, - rect_t * outer) -{ - int min_left, max_left, min_right, max_right; - int min_top, max_top, min_bottom, max_bottom; - - if (a.left < b.left) { - max_left = b.left; - min_left = a.left; - } else { - max_left = a.left; - min_left = b.left; - } - - if (a.right < b.right) { - min_right = a.right; - max_right = b.right; - } else { - min_right = b.right; - max_right = a.right; - } - - intra->left = max_left; - intra->right = min_right; - intra->width = min_right - max_left; - - outer->left = min_left; - outer->right = max_right; - outer->width = max_right - min_left; - - if (a.top < b.top) { - max_top = b.top; - min_top = a.top; - } else { - max_top = a.top; - min_top = b.top; - } - - if (a.bottom < b.bottom) { - min_bottom = a.bottom; - max_bottom = b.bottom; - } else { - min_bottom = b.bottom; - max_bottom = a.bottom; - } - - intra->top = max_top; - intra->bottom = min_bottom; - intra->height = min_bottom - max_top; - if ((intra->width > 0) && (intra->height > 0)) - intra->area = intra->width * intra->height; - else - intra->area = 0; - - outer->top = min_top; - outer->bottom = max_bottom; - outer->height = max_bottom - min_top; - outer->area = outer->width * outer->height; -} - -enum { - SPLIT_FUZZY_ACTION_NONE, - SPLIT_FUZZY_ACTION_SPLIT, - SPLIT_FUZZY_ACTION_MERGE -}; - -static inline int _split_fuzzy(list_t * dirty, const rect_t a, rect_t * b) -{ - int h_1, h_2, w_1, w_2, action; - - h_1 = a.top - b->top; - h_2 = b->bottom - a.bottom; - w_1 = a.left - b->left; - w_2 = b->right - a.right; - - action = SPLIT_FUZZY_ACTION_NONE; - - if (h_1 > 0) { - /* .--.r (b) .---.r2 - * | | | | - * .-------.cur (a) .---.r '---' - * | | | | -> | | + - * | `--' | `---' - * `-------' - */ - rect_list_append_xywh(dirty, b->left, b->top, b->width, - h_1); - b->height -= h_1; - b->top = a.top; - action = SPLIT_FUZZY_ACTION_SPLIT; - } - - if (h_2 > 0) { - /* .-------.cur (a) - * | .---. | .---.r - * | | | | -> | | - * `-------' `---' + .---.r2 - * | | | | - * `---'r (b) `---' - */ - rect_list_append_xywh(dirty, b->left, a.bottom, b->width, - h_2); - b->height -= h_2; - action = SPLIT_FUZZY_ACTION_SPLIT; - } - - if (((w_1 > 0) || (w_2 > 0)) && (a.height == b->height)) - return SPLIT_FUZZY_ACTION_MERGE; - - if (w_1 > 0) { - /* (b) r .----.cur (a) - * .--|-. | .--.r2 .-.r - * | | | | -> | | + | | - * `--|-' | `--' `-' - * `----' - */ - rect_list_append_xywh(dirty, b->left, b->top, w_1, - b->height); - /* not necessary to keep these, r (b) will be destroyed */ - /* b->width -= w_1; */ - /* b->left = a.left; */ - action = SPLIT_FUZZY_ACTION_SPLIT; - } - - if (w_2 > 0) { - /* .----.cur (a) - * | | - * | .-|--.r (b) .-.r .--.r2 - * | | | | -> | | + | | - * | `-|--' `-' `--' - * `----' - */ - rect_list_append_xywh(dirty, a.right, b->top, w_2, - b->height); - /* not necessary to keep these, r (b) will be destroyed */ - /* b->width -= w_2; */ - action = SPLIT_FUZZY_ACTION_SPLIT; - } - - return action; -} - -#if 0 -static void rect_list_node_pool_set_max(int max) -{ - int diff; - - diff = list_node_pool.len - max; - for (; diff > 0 && list_node_pool.node != NULL; diff--) { - list_node_t *node; - - node = list_node_pool.node; - list_node_pool.node = node->next; - list_node_pool.len--; - - free(node); - } - - list_node_pool.max = max; -} -#endif - -static void rect_list_node_pool_flush(void) -{ - while (list_node_pool.node) { - list_node_t *node; - - node = list_node_pool.node; - list_node_pool.node = node->next; - list_node_pool.len--; - - free(node); - } -} - - - -static inline void rect_list_node_pool_put(list_node_t * node) -{ - if (list_node_pool.len < list_node_pool.max) { - node->next = list_node_pool.node; - list_node_pool.node = node; - list_node_pool.len++; - } else - free(node); -} - -#if 0 -static void rect_print(const rect_t r) -{ - printf("<rect(%d, %d, %d, %d)>", r.left, r.top, r.width, r.height); -} - -static void rect_list_print(const list_t rects) -{ - list_node_t *node; - int len; - - len = 0; - for (node = rects.head; node != NULL; node = node->next) - len++; - - printf("["); - for (node = rects.head; node != NULL; node = node->next) { - rect_print(((rect_node_t *) node)->rect); - if (node->next) { - putchar(','); - if (len < 4) - putchar(' '); - else { - putchar('\n'); - putchar(' '); - } - } - } - printf("]\n"); -} -#endif - -static inline list_node_t *rect_list_unlink_next(list_t * rects, - list_node_t * parent_node) -{ - list_node_t *node; - - if (parent_node) { - node = parent_node->next; - parent_node->next = node->next; - } else { - node = rects->head; - rects->head = node->next; - } - - if (rects->tail == node) - rects->tail = parent_node; - - *node = list_node_zeroed; - return node; -} - -static inline void rect_list_del_next(list_t * rects, - list_node_t * parent_node) -{ - list_node_t *node; - - node = rect_list_unlink_next(rects, parent_node); - rect_list_node_pool_put(node); -} - -static void rect_list_clear(list_t * rects) -{ - list_node_t *node; - - node = rects->head; - while (node) { - list_node_t *aux; - - aux = node->next; - rect_list_node_pool_put(node); - node = aux; - } - *rects = list_zeroed; -} - -static void rect_list_del_split_strict(list_t * rects, const rect_t del_r) -{ - list_t modified = list_zeroed; - list_node_t *cur_node, *prev_node; - - prev_node = NULL; - cur_node = rects->head; - while (cur_node) { - int intra_width, intra_height; - rect_t current; - - current = ((rect_node_t *) cur_node)->rect; - - _calc_intra_rect_area(del_r, current, &intra_width, - &intra_height); - if ((intra_width <= 0) || (intra_height <= 0)) { - /* .---.current .---.del_r - * | | | | - * `---+---.del_r `---+---.current - * | | | | - * `---' `---' - * no intersection, nothing to do - */ - prev_node = cur_node; - cur_node = cur_node->next; - } else if ((intra_width == current.width) && (intra_height - == - current. - height)) { - /* .-------.del_r - * | .---. | - * | | | | - * | `---'current - * `-------' - * current is contained, remove from rects - */ - cur_node = cur_node->next; - rect_list_del_next(rects, prev_node); - } else { - _split_strict(&modified, del_r, current); - cur_node = cur_node->next; - rect_list_del_next(rects, prev_node); - } - } - - rect_list_concat(rects, &modified); -} - -#if 0 -static void rect_list_add_split_strict(list_t * rects, list_node_t * node) -{ - list_t dirty = list_zeroed; - list_t new_dirty = list_zeroed; - list_node_t *cur_node; - - if (!rects->head) { - rect_list_append_node(rects, node); - return; - } - - rect_list_append_node(&dirty, node); - - cur_node = rects->head; - while (dirty.head) { - rect_t current; - - if (!cur_node) { - rect_list_concat(rects, &dirty); - break; - } - - current = ((rect_node_t *) cur_node)->rect; - - while (dirty.head) { - int intra_width, intra_height; - rect_t r; - - r = ((rect_node_t *) dirty.head)->rect; - _calc_intra_rect_area(r, current, &intra_width, - &intra_height); - if ((intra_width == r.width) && (intra_height - == r.height)) - /* .-------.cur - * | .---.r| - * | | | | - * | `---' | - * `-------' - */ - rect_list_del_next(&dirty, NULL); - else if ((intra_width <= 0) || (intra_height <= 0)) { - /* .---.cur .---.r - * | | | | - * `---+---.r `---+---.cur - * | | | | - * `---' `---' - */ - list_node_t *tmp; - tmp = rect_list_unlink_next(&dirty, NULL); - rect_list_append_node(&new_dirty, tmp); - } else { - _split_strict(&new_dirty, current, r); - rect_list_del_next(&dirty, NULL); - } - } - dirty = new_dirty; - new_dirty = list_zeroed; - - cur_node = cur_node->next; - } -} -#endif - -static list_node_t *rect_list_add_split_fuzzy(list_t * rects, - list_node_t * node, - int accepted_error) -{ - list_t dirty = list_zeroed; - list_node_t *old_last; - - old_last = rects->tail; - - if (!rects->head) { - rect_list_append_node(rects, node); - return old_last; - } - - rect_list_append_node(&dirty, node); - while (dirty.head) { - list_node_t *d_node, *cur_node, *prev_cur_node; - int keep_dirty; - rect_t r; - - d_node = rect_list_unlink_next(&dirty, NULL); - r = ((rect_node_t *) d_node)->rect; - - prev_cur_node = NULL; - cur_node = rects->head; - keep_dirty = 1; - while (cur_node) { - int area, action; - rect_t current, intra, outer; - - current = ((rect_node_t *) cur_node)->rect; - - _calc_intra_outer_rect_area(r, current, &intra, - &outer); - area = current.area + r.area - intra.area; - - if ((intra.width == r.width) && (intra.height - == r.height)) { - /* .-------.cur - * | .---.r| - * | | | | - * | `---' | - * `-------' - */ - keep_dirty = 0; - break; - } else if ((intra.width == current.width) - && (intra.height == current.height)) { - /* .-------.r - * | .---.cur - * | | | | - * | `---' | - * `-------' - */ - if (old_last == cur_node) - old_last = prev_cur_node; - - cur_node = cur_node->next; - rect_list_del_next(rects, prev_cur_node); - } else if ((outer.area - area) <= accepted_error) { - /* .-----------. bounding box (outer) - * |.---. .---.| - * ||cur| |r || - * || | | || - * |`---' `---'| - * `-----------' - * merge them, remove both and add merged - */ - rect_node_t *n; - - if (old_last == cur_node) - old_last = prev_cur_node; - - n = (rect_node_t *) - rect_list_unlink_next(rects, - prev_cur_node); - n->rect = outer; - rect_list_append_node(&dirty, - (list_node_t *) n); - - keep_dirty = 0; - break; - } else if (intra.area <= accepted_error) { - /* .---.cur .---.r - * | | | | - * `---+---.r `---+---.cur - * | | | | - * `---' `---' - * no split, no merge - */ - prev_cur_node = cur_node; - cur_node = cur_node->next; - } else { - /* split is required */ - action = _split_fuzzy(&dirty, current, &r); - if (action == SPLIT_FUZZY_ACTION_MERGE) { -/* horizontal merge is possible: remove both, add merged */ - rect_node_t *n; - - if (old_last == cur_node) - old_last = prev_cur_node; - - n = (rect_node_t *) - rect_list_unlink_next(rects, - prev_cur_node); - - n->rect.left = outer.left; - n->rect.width = outer.width; - n->rect.right = outer.right; - n->rect.area = - outer.width * r.height; - rect_list_append_node(&dirty, - (list_node_t - *) n); - } else if (action == - SPLIT_FUZZY_ACTION_NONE) { -/* - * this rect check was totally useless, - * should never happen - */ -/* prev_cur_node = cur_node; */ -/* cur_node = cur_node->next; */ - printf("Should not get here!\n"); - abort(); - } - - keep_dirty = 0; - break; - } - } - if (EINA_UNLIKELY(keep_dirty)) - rect_list_append_node(rects, d_node); - else - rect_list_node_pool_put(d_node); - } - - return old_last; -} - -static inline void _calc_outer_rect_area(const rect_t a, const rect_t b, - rect_t * outer) -{ - int min_left, max_right; - int min_top, max_bottom; - - if (a.left < b.left) - min_left = a.left; - else - min_left = b.left; - - if (a.right < b.right) - max_right = b.right; - else - max_right = a.right; - - outer->left = min_left; - outer->right = max_right; - outer->width = max_right - min_left; - - if (a.top < b.top) - min_top = a.top; - else - min_top = b.top; - - if (a.bottom < b.bottom) - max_bottom = b.bottom; - else - max_bottom = a.bottom; - - outer->top = min_top; - outer->bottom = max_bottom; - outer->height = max_bottom - min_top; - - outer->area = outer->width * outer->height; -} - -static void rect_list_merge_rects(list_t * rects, - list_t * to_merge, int accepted_error) -{ - while (to_merge->head) { - list_node_t *node, *parent_node; - rect_t r1; - int merged; - - r1 = ((rect_node_t *) to_merge->head)->rect; - - merged = 0; - parent_node = NULL; - node = rects->head; - while (node) { - rect_t r2, outer; - int area; - - r2 = ((rect_node_t *) node)->rect; - - _calc_outer_rect_area(r1, r2, &outer); - area = r1.area + r2.area; /* intra area is taken as 0 */ - if (outer.area - area <= accepted_error) { - /* - * remove both r1 and r2, create r3 - * actually r3 uses r2 instance, saves memory - */ - rect_node_t *n; - - n = (rect_node_t *) - rect_list_unlink_next(rects, - parent_node); - n->rect = outer; - rect_list_append_node(to_merge, - (list_node_t *) n); - merged = 1; - break; - } - - parent_node = node; - node = node->next; - } - - if (!merged) { - list_node_t *n; - n = rect_list_unlink_next(to_merge, NULL); - rect_list_append_node(rects, n); - } else - rect_list_del_next(to_merge, NULL); - } -} - -static void rect_list_add_split_fuzzy_and_merge(list_t * rects, - list_node_t * node, - int split_accepted_error, - int merge_accepted_error) -{ - list_node_t *n; - - n = rect_list_add_split_fuzzy(rects, node, split_accepted_error); - if (n && n->next) { - list_t to_merge; - - /* split list into 2 segments, already merged and to merge */ - to_merge.head = n->next; - to_merge.tail = rects->tail; - rects->tail = n; - n->next = NULL; - - rect_list_merge_rects(rects, &to_merge, - merge_accepted_error); - } -} - -static inline void _splitter_new(Eina_Tiler * t) -{ - t->splitter.rects = list_zeroed; - t->splitter.need_merge = EINA_FALSE; -} - -static inline void _splitter_del(Eina_Tiler * t) -{ - rect_list_clear(&t->splitter.rects); - rect_list_node_pool_flush(); -} - -static inline void _splitter_tile_size_set(Eina_Tiler * t, - int w __UNUSED__, - int h __UNUSED__) -{ - /* TODO are w and h used for something? */ - t->splitter.rects = list_zeroed; -} - -static inline Eina_Bool _splitter_rect_add(Eina_Tiler * t, - Eina_Rectangle * rect) -{ - rect_node_t *rn; - - //printf("ACCOUNTING[1]: add_redraw: %4d,%4d %3dx%3d\n", x, y, w, h); - rect->x >>= 1; - rect->y >>= 1; - rect->w += 2; - rect->w >>= 1; - rect->h += 2; - rect->h >>= 1; - - rn = (rect_node_t *) rect_list_node_pool_get(); - rn->_lst = list_node_zeroed; - rect_init(&rn->rect, rect->x, rect->y, rect->w, rect->h); - //printf("ACCOUNTING[2]: add_redraw: %4d,%4d %3dx%3d\n", x, y, w, h); - //testing on my core2 duo desktop - fuzz of 32 or 48 is best. -#define FUZZ 32 - rect_list_add_split_fuzzy_and_merge(&t->splitter.rects, - (list_node_t *) rn, - FUZZ * FUZZ, FUZZ * FUZZ); - return EINA_TRUE; -} - -static inline void _splitter_rect_del(Eina_Tiler * t, - Eina_Rectangle * rect) -{ - rect_t r; - - if (!t->splitter.rects.head) - return; - - rect->x += 1; - rect->y += 1; - rect->x >>= 1; - rect->y >>= 1; - rect->w -= 1; - rect->w >>= 1; - rect->h -= 1; - rect->h >>= 1; - - if ((rect->w <= 0) || (rect->h <= 0)) - return; - - rect_init(&r, rect->x, rect->y, rect->w, rect->h); - //fprintf(stderr, "ACCOUNTING: del_redraw: %4d,%4d %3dx%3d\n", x, y, w, h); - - rect_list_del_split_strict(&t->splitter.rects, r); - t->splitter.need_merge = EINA_TRUE; - return; -} - -static inline void _splitter_clear(Eina_Tiler * t) -{ - rect_list_clear(&t->splitter.rects); - t->splitter.need_merge = EINA_FALSE; -} - -/* end of splitter algorithm */ - -static Eina_Bool _iterator_next(Eina_Iterator_Tiler * it, void **data) -{ - Eina_Rectangle *rect = (Eina_Rectangle *) data; - list_node_t *n; - - for (n = it->curr; n; n = n->next) { - rect_t cur; - - cur = ((rect_node_t *) n)->rect; - - rect->x = cur.left << 1; - rect->y = cur.top << 1; - rect->w = cur.width << 1; - rect->h = cur.height << 1; - - if (eina_rectangle_intersection(rect, &it->tiler->area) == - EINA_FALSE) - continue; - - if ((rect->w <= 0) || (rect->h <= 0)) - continue; - - it->curr = n->next; - return EINA_TRUE; - } - return EINA_FALSE; -} - -static void *_iterator_get_container(Eina_Iterator_Tiler * it) -{ - EINA_MAGIC_CHECK_TILER_ITERATOR(it, NULL); - return (void *) it->tiler; -} - -static void _iterator_free(Eina_Iterator_Tiler * it) -{ - EINA_MAGIC_CHECK_TILER_ITERATOR(it); - free(it); -} - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -EAPI Eina_Tiler *eina_tiler_new(int w, int h) -{ - Eina_Tiler *t; - - t = calloc(1, sizeof(Eina_Tiler)); - t->area.w = w; - t->area.h = h; - t->tile.w = w; - t->tile.h = h; - EINA_MAGIC_SET(t, EINA_MAGIC_TILER); - _splitter_new(t); - return t; -} - -EAPI void eina_tiler_free(Eina_Tiler * t) -{ - EINA_MAGIC_CHECK_TILER(t); - _splitter_del(t); - free(t); -} - -EAPI void eina_tiler_tile_size_set(Eina_Tiler * t, int w, int h) -{ - EINA_MAGIC_CHECK_TILER(t); - if ((w <= 0) || (h <= 0)) - return; - - t->tile.w = w; - t->tile.h = h; - _splitter_tile_size_set(t, w, h); -} - -EAPI Eina_Bool eina_tiler_rect_add(Eina_Tiler * t, - const Eina_Rectangle * r) -{ - Eina_Rectangle tmp; - - EINA_MAGIC_CHECK_TILER(t, EINA_FALSE); - if ((r->w <= 0) || (r->h <= 0)) - return EINA_FALSE; - - tmp = *r; - if (eina_rectangle_intersection(&tmp, &t->area) == EINA_FALSE) - return EINA_FALSE; - - if ((tmp.w <= 0) || (tmp.h <= 0)) - return EINA_FALSE; - - return _splitter_rect_add(t, &tmp); -} - -EAPI void eina_tiler_rect_del(Eina_Tiler * t, const Eina_Rectangle * r) -{ - Eina_Rectangle tmp; - - EINA_MAGIC_CHECK_TILER(t); - if ((r->w <= 0) || (r->h <= 0)) - return; - - tmp = *r; - if (eina_rectangle_intersection(&tmp, &t->area) == EINA_FALSE) - return; - - if ((tmp.w <= 0) || (tmp.h <= 0)) - return; - - _splitter_rect_del(t, &tmp); -} - -EAPI void eina_tiler_clear(Eina_Tiler * t) -{ - EINA_MAGIC_CHECK_TILER(t); - _splitter_clear(t); -} - - -EAPI Eina_Iterator *eina_tiler_iterator_new(const Eina_Tiler * t) -{ - Eina_Iterator_Tiler *it; - - EINA_MAGIC_CHECK_TILER(t, NULL); - - it = calloc(1, sizeof(Eina_Iterator_Tiler)); - if (!it) - return NULL; - - it->tiler = t; - - if (t->splitter.need_merge == EINA_TRUE) { - list_t to_merge; - splitter_t *sp; - - sp = (splitter_t *) & (t->splitter); - to_merge = t->splitter.rects; - sp->rects = list_zeroed; - rect_list_merge_rects(&sp->rects, &to_merge, FUZZ * FUZZ); - sp->need_merge = 0; - } - - it->curr = it->tiler->splitter.rects.head; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_iterator_next); - it->iterator.get_container = - FUNC_ITERATOR_GET_CONTAINER(_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(_iterator_free); - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - EINA_MAGIC_SET(it, EINA_MAGIC_TILER_ITERATOR); - - return &it->iterator; -} - -struct _Eina_Tile_Grid_Slicer_Iterator { - Eina_Iterator iterator; - Eina_Tile_Grid_Slicer priv; -}; - -typedef struct _Eina_Tile_Grid_Slicer_Iterator - Eina_Tile_Grid_Slicer_Iterator; - -static void -eina_tile_grid_slicer_iterator_free(Eina_Tile_Grid_Slicer_Iterator * it) -{ - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE); - free(it); -} - -static Eina_Bool -eina_tile_grid_slicer_iterator_next(Eina_Tile_Grid_Slicer_Iterator * it, - void **data) -{ - return eina_tile_grid_slicer_next - (&it->priv, (const Eina_Tile_Grid_Info **) data); -} - -/** - * @brief Creates a new Eina_Iterator that slices over a list of tiles. - * - * @param x X axis coordinate. - * @param y Y axis coordinate. - * @param w width. - * @param h height. - * @param tile_w tile width. - * @param tile_h tile height. - * @return A pointer to the Eina_Iterator. - * @c NULL on failure. - * - * The tile grid is defined by @a tile_w and @a tile_h while the region is - * defined by @a x, @a y, @a w, @a h. The output is given as - * @c Eina_Tile_Grid_Info where tile index is given in @c col col and - * @c row row with tile-relative - * coordinates in @c x, @c y, @c w, @c h. If tile was fully filled by - * region, then @c full flag - * is set. - */ -EAPI Eina_Iterator *eina_tile_grid_slicer_iterator_new(int x, - int y, - int w, - int h, - int tile_w, - int tile_h) -{ - Eina_Tile_Grid_Slicer_Iterator *it; - - it = calloc(1, sizeof(*it)); - if (!it) { - eina_error_set(EINA_ERROR_OUT_OF_MEMORY); - return NULL; - } - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = - FUNC_ITERATOR_NEXT(eina_tile_grid_slicer_iterator_next); - it->iterator.free = - FUNC_ITERATOR_FREE(eina_tile_grid_slicer_iterator_free); - - eina_tile_grid_slicer_setup(&it->priv, x, y, w, h, tile_w, tile_h); - - return &it->iterator; -} diff --git a/tests/suite/ecore/src/lib/eina_unicode.c b/tests/suite/ecore/src/lib/eina_unicode.c deleted file mode 100644 index e4fa7be83b..0000000000 --- a/tests/suite/ecore/src/lib/eina_unicode.c +++ /dev/null @@ -1,166 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2010 Tom Hacohen, - * 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 <https://www.gnu.org/licenses/>. - - */ - -#include <Eina.h> -#include "eina_unicode.h" - -/* FIXME: check if sizeof(wchar_t) == sizeof(Eina_Unicode) if so, - * probably better to use the standard functions */ - -/* Maybe I'm too tired, but this is the only thing that actually worked. */ -const Eina_Unicode _EINA_UNICODE_EMPTY_STRING[1] = { 0 }; - -EAPI const Eina_Unicode *EINA_UNICODE_EMPTY_STRING = - _EINA_UNICODE_EMPTY_STRING; -/** - * @brief Same as the standard strcmp just with Eina_Unicode instead of char. - */ -EAPI int -eina_unicode_strcmp(const Eina_Unicode * a, const Eina_Unicode * b) -{ - for (; *a && *a == *b; a++, b++); - if (*a == *b) - return 0; - else if (*a < *b) - return -1; - else - return 1; -} - -/** - * @brief Same as the standard strcpy just with Eina_Unicode instead of char. - */ -EAPI Eina_Unicode *eina_unicode_strcpy(Eina_Unicode * dest, - const Eina_Unicode * source) -{ - Eina_Unicode *ret = dest; - - while (*source) - *dest++ = *source++; - *dest = 0; - return ret; -} - -/** - * @brief Same as the standard strncpy just with Eina_Unicode instead of char. - */ -EAPI Eina_Unicode *eina_unicode_strncpy(Eina_Unicode * dest, - const Eina_Unicode * source, - size_t n) -{ - Eina_Unicode *ret = dest; - - for (; n && *source; n--) - *dest++ = *source++; - for (; n; n--) - *dest++ = 0; - return ret; -} - -/** - * @brief Same as the standard strlen just with Eina_Unicode instead of char. - */ -EAPI size_t eina_unicode_strlen(const Eina_Unicode * ustr) -{ - const Eina_Unicode *end; - for (end = ustr; *end; end++); - return end - ustr; -} - -/** - * @brief Returns the length of a Eina_Unicode string, up to a limit. - * - * This function returns the number of characters in string, up to a maximum - * of n. If the terminating character is not found in the string, it returns - * n. - * - * @param ustr String to search - * @param n Max length to search - * @return Number of characters or n. - */ -EAPI size_t eina_unicode_strnlen(const Eina_Unicode * ustr, int n) -{ - const Eina_Unicode *end; - const Eina_Unicode *last = ustr + n; /* technically not portable ;-) */ - for (end = ustr; end < last && *end; end++); - return end - ustr; -} - - - - -/** - * @brief Same as the standard strdup just with Eina_Unicode instead of char. - */ -EAPI Eina_Unicode *eina_unicode_strdup(const Eina_Unicode * text) -{ - Eina_Unicode *ustr; - int len; - - len = eina_unicode_strlen(text); - ustr = (Eina_Unicode *) calloc(len + 1, sizeof(Eina_Unicode)); - memcpy(ustr, text, len * sizeof(Eina_Unicode)); - - return ustr; -} - -/** - * @brief Same as the standard strdup just with Eina_Unicode instead of char. - */ -EAPI Eina_Unicode *eina_unicode_strstr(const Eina_Unicode * haystack, - const Eina_Unicode * needle) -{ - const Eina_Unicode *i, *j; - - for (i = haystack; *i; i++) { - haystack = i; /* set this location as the base position */ - for (j = needle; *j && *i && *j == *i; j++, i++); - - if (!*j) { /*if we got to the end of j this means we got a full match */ - return (Eina_Unicode *) haystack; /* return the new base position */ - } - } - - return NULL; -} - -/** - * @see eina_str_escape() - */ -EAPI Eina_Unicode *eina_unicode_escape(const Eina_Unicode * str) -{ - Eina_Unicode *s2, *d; - const Eina_Unicode *s; - - s2 = malloc((eina_unicode_strlen(str) * 2) + 1); - if (!s2) - return NULL; - - for (s = str, d = s2; *s != 0; s++, d++) { - if ((*s == ' ') || (*s == '\\') || (*s == '\'')) { - *d = '\\'; - d++; - } - - *d = *s; - } - *d = 0; - return s2; -} diff --git a/tests/suite/ecore/src/lib/eina_ustrbuf.c b/tests/suite/ecore/src/lib/eina_ustrbuf.c deleted file mode 100644 index f571ef61a6..0000000000 --- a/tests/suite/ecore/src/lib/eina_ustrbuf.c +++ /dev/null @@ -1,89 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "eina_strbuf_common.h" -#include "eina_unicode.h" -#include "eina_ustrbuf.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - -#ifdef _STRBUF_DATA_TYPE -#undef _STRBUF_DATA_TYPE -#endif - -#ifdef _STRBUF_CSIZE -#undef _STRBUF_CSIZE -#endif - -#ifdef _STRBUF_STRUCT_NAME -#undef _STRBUF_STRUCT_NAME -#endif - -#ifdef _STRBUF_STRLEN_FUNC -#undef _STRBUF_STRLEN_FUNC -#endif - -#ifdef _STRBUF_STRESCAPE_FUNC -#undef _STRBUF_STRESCAPE_FUNC -#endif - -#ifdef _STRBUF_MAGIC -#undef _STRBUF_MAGIC -#endif - -#ifdef _STRBUF_MAGIC_STR -#undef _STRBUF_MAGIC_STR -#endif - -#ifdef _FUNC_EXPAND -#undef _FUNC_EXPAND -#endif - -#define _STRBUF_DATA_TYPE Eina_Unicode -#define _STRBUF_CSIZE sizeof(_STRBUF_DATA_TYPE) -#define _STRBUF_STRUCT_NAME Eina_UStrbuf -#define _STRBUF_STRLEN_FUNC(x) eina_unicode_strlen(x) -#define _STRBUF_STRESCAPE_FUNC(x) eina_unicode_escape(x) -#define _STRBUF_MAGIC EINA_MAGIC_USTRBUF -#define _STRBUF_MAGIC_STR __USTRBUF_MAGIC_STR -static const char __USTRBUF_MAGIC_STR[] = "Eina UStrbuf"; - -#define _FUNC_EXPAND(y) eina_ustrbuf_ ## y - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Eina_Unicode_String_Buffer_Group Unicode String Buffer - * - * @brief These functions provide unicode string buffers management. - * - * The Unicode String Buffer data type is designed to be a mutable string, - * allowing to append, prepend or insert a string to a buffer. - * - * @{ - */ - -#include "eina_strbuf_template_c.x" - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_ustringshare.c b/tests/suite/ecore/src/lib/eina_ustringshare.c deleted file mode 100644 index fc0db80c01..0000000000 --- a/tests/suite/ecore/src/lib/eina_ustringshare.c +++ /dev/null @@ -1,237 +0,0 @@ -/* EINA - EFL data type library - * Copyright (C) 2002-2008 Carsten Haitzler, - * Jorge Luis Zapata Muga, - * Cedric Bail, - * Gustavo Sverzut Barbieri - * Tom Hacohen - * - * 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 <https://www.gnu.org/licenses/>. - - */ -/** - * @page tutorial_ustringshare_page UStringshare Tutorial - * - * to be written... - * - */ - -#include "eina_share_common.h" -#include "eina_unicode.h" -#include "eina_private.h" -#include "eina_ustringshare.h" - -/* The actual share */ -static Eina_Share *ustringshare_share; -static const char EINA_MAGIC_USTRINGSHARE_NODE_STR[] = - "Eina UStringshare Node"; - -/*============================================================================* -* Global * -*============================================================================*/ - -/** - * @internal - * @brief Initialize the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function sets up the share_common module of Eina. It is called by - * eina_init(). - * - * @see eina_init() - */ -Eina_Bool eina_ustringshare_init(void) -{ - return eina_share_common_init(&ustringshare_share, - EINA_MAGIC_USTRINGSHARE_NODE, - EINA_MAGIC_USTRINGSHARE_NODE_STR); -} - -/** - * @internal - * @brief Shut down the share_common module. - * - * @return #EINA_TRUE on success, #EINA_FALSE on failure. - * - * This function shuts down the share_common module set up by - * eina_share_common_init(). It is called by eina_shutdown(). - * - * @see eina_shutdown() - */ -Eina_Bool eina_ustringshare_shutdown(void) -{ - Eina_Bool ret; - ret = eina_share_common_shutdown(&ustringshare_share); - return ret; -} - -/*============================================================================* -* API * -*============================================================================*/ -/** - * @addtogroup Eina_UStringshare_Group Unicode Stringshare - * - * 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. - * - * For more information, you can look at the @ref tutorial_ustringshare_page. - * - * @{ - */ - -/** - * @brief Note that the given string has lost an instance. - * - * @param str string The given string. - * - * This function decreases the reference counter associated to @p str - * if it exists. If that counter reaches 0, the memory associated to - * @p str is freed. If @p str is NULL, the function returns - * immediately. - * - * Note that if the given pointer is not shared or NULL, bad things - * will happen, likely a segmentation fault. - */ -EAPI void eina_ustringshare_del(const Eina_Unicode * str) -{ - if (!str) - return; - - eina_share_common_del(ustringshare_share, (const char *) str); -} - -/** - * @brief Retrieve an instance of a string for use in a program. - * - * @param str The string to retrieve an instance of. - * @param slen The string size (<= strlen(str)). - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p str. If @p str is - * @c NULL, then @c NULL is returned. If @p str is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the strings to be searched and a duplicated string - * of @p str is returned. - * - * This function does not check string size, but uses the - * exact given size. This can be used to share_common part of a larger - * buffer or substring. - * - * @see eina_ustringshare_add() - */ -EAPI const Eina_Unicode *eina_ustringshare_add_length(const Eina_Unicode * - str, - unsigned int slen) -{ - return (const Eina_Unicode *) - eina_share_common_add_length(ustringshare_share, - (const char *) str, - slen * sizeof(Eina_Unicode), - sizeof(Eina_Unicode)); -} - -/** - * @brief Retrieve an instance of a string for use in a program. - * - * @param str The NULL terminated string to retrieve an instance of. - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This function retrieves an instance of @p str. If @p str is - * @c NULL, then @c NULL is returned. If @p str is already stored, it - * is just returned and its reference counter is increased. Otherwise - * it is added to the strings to be searched and a duplicated string - * of @p str is returned. - * - * The string @p str must be NULL terminated ('@\0') and its full - * length will be used. To use part of the string or non-null - * terminated, use eina_stringshare_add_length() instead. - * - * @see eina_ustringshare_add_length() - */ -EAPI const Eina_Unicode *eina_ustringshare_add(const Eina_Unicode * str) -{ - int slen = (str) ? (int) eina_unicode_strlen(str) : -1; - return eina_ustringshare_add_length(str, slen); -} - -/** - * Increment references of the given shared string. - * - * @param str The shared string. - * @return A pointer to an instance of the string on success. - * @c NULL on failure. - * - * This is similar to eina_share_common_add(), but it's faster since it will - * avoid lookups if possible, but on the down side it requires the parameter - * to be shared before, in other words, it must be the return of a previous - * eina_ustringshare_add(). - * - * There is no unref since this is the work of eina_ustringshare_del(). - */ -EAPI const Eina_Unicode *eina_ustringshare_ref(const Eina_Unicode * str) -{ - return (const Eina_Unicode *) - eina_share_common_ref(ustringshare_share, (const char *) str); -} - -/** - * @brief Note that the given string @b must be shared. - * - * @param str the shared string to know the length. It is safe to - * give NULL, in that case -1 is returned. - * - * This function is a cheap way to known the length of a shared - * string. Note that if the given pointer is not shared, bad - * things will happen, likely a segmentation fault. If in doubt, try - * strlen(). - */ -EAPI int eina_ustringshare_strlen(const Eina_Unicode * str) -{ - int len = - eina_share_common_length(ustringshare_share, - (const char *) str); - len = (len > 0) ? len / (int) sizeof(Eina_Unicode) : -1; - return len; -} - -/** - * @brief Dump the contents of the share_common. - * - * This function dumps all strings in the share_common to stdout with a - * DDD: prefix per line and a memory usage summary. - */ -EAPI void eina_ustringshare_dump(void) -{ - eina_share_common_dump(ustringshare_share, NULL, 0); -} - -/** - * @} - */ diff --git a/tests/suite/ecore/src/lib/eina_value.c b/tests/suite/ecore/src/lib/eina_value.c deleted file mode 100644 index 7115a3063a..0000000000 --- a/tests/suite/ecore/src/lib/eina_value.c +++ /dev/null @@ -1,47 +0,0 @@ -/* eina_value.c - - Copyright (C) 2001 Christopher Rosendahl <smugg@fatelabs.com> - Nathan Ingersoll <ningerso@d.umn.edu> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies of the Software and its documentation and acknowledgment shall be - given in the documentation and software packages that this Software was - used. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "eina_config.h" -#include "eina_private.h" - -/*============================================================================* -* Global * -*============================================================================*/ - -/*============================================================================* -* API * -*============================================================================*/ - -EAPI const unsigned int eina_prime_table[] = { - 17, 31, 61, 127, 257, 509, 1021, - 2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, - 1048573, - 2097143, 4194301, 8388617, 16777213 -}; diff --git a/tests/suite/mini-eagain2.c b/tests/suite/mini-eagain2.c deleted file mode 100644 index 5b09622b7b..0000000000 --- a/tests/suite/mini-eagain2.c +++ /dev/null @@ -1,223 +0,0 @@ -#include <config.h> -#include <Ecore.h> -#include <fcntl.h> -#include <netinet/tcp.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <errno.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "../utils.h" -#include <gnutls/gnutls.h> - -/* Ecore_Fd_Handler example - * 2010 Mike Blumenkrantz - * compile with gcc $(pkgconfig --cflags --libs gnutls ecore) - */ - - -#define print(...) {fprintf(stderr, "line %i: ", __LINE__); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n");} - -static int done = 0; - -#if 0 -static void tls_log_func(int level, const char *str) -{ - fprintf(stderr, "|<%d>| %s", level, str); -} -#endif - -static const char - *SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t - status) -{ - switch (status) { - case GNUTLS_HANDSHAKE_HELLO_REQUEST: - return "Hello request"; - case GNUTLS_HANDSHAKE_CLIENT_HELLO: - return "Client hello"; - case GNUTLS_HANDSHAKE_SERVER_HELLO: - return "Server hello"; - case GNUTLS_HANDSHAKE_CERTIFICATE_PKT: - return "Certificate packet"; - case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE: - return "Server key exchange"; - case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST: - return "Certificate request"; - case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE: - return "Server hello done"; - case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY: - return "Certificate verify"; - case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE: - return "Client key exchange"; - case GNUTLS_HANDSHAKE_FINISHED: - return "Finished"; - case GNUTLS_HANDSHAKE_SUPPLEMENTAL: - return "Supplemental"; - default: - return NULL; - } - return NULL; -} - -/* Connects to the peer and returns a socket - * descriptor. - */ -static int tcp_connect(void) -{ - const char *PORT = getenv("PORT"); - const char *SERVER = "127.0.0.1"; //verisign.com - int err, sd; - int flag = 1, curstate = 0; - struct sockaddr_in sa; - - /* sets some fd options such as nonblock */ - sd = socket(AF_INET, SOCK_STREAM, 0); - fcntl(sd, F_SETFL, O_NONBLOCK); - fcntl(sd, F_SETFD, FD_CLOEXEC); - setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const void *) &curstate, - sizeof(curstate)); - - setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, - sizeof(int)); - - memset(&sa, '\0', sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = htons(atoi(PORT)); - inet_pton(AF_INET, SERVER, &sa.sin_addr); - - /* connects to server - */ - err = connect(sd, (struct sockaddr *) &sa, sizeof(sa)); - if ((err < 0) && (errno != EINPROGRESS)) { - print("Connect error\n"); - exit(1); - } - - return sd; -} - -/* closes the given socket descriptor. - */ -static void tcp_close(int sd) -{ - shutdown(sd, SHUT_RDWR); /* no more receptions */ - close(sd); -} - -static Eina_Bool -_process_data(gnutls_session_t client, Ecore_Fd_Handler * fd_handler) -{ - static int ret, lastret; - static unsigned int count = 0; - - if (!done) { - lastret = ret; - ret = gnutls_handshake(client); - count++; - if (gnutls_record_get_direction(client)) - ecore_main_fd_handler_active_set(fd_handler, - ECORE_FD_WRITE); - else - ecore_main_fd_handler_active_set(fd_handler, - ECORE_FD_READ); - /* avoid printing messages infinity times */ - if (lastret != ret && ret != 0 && ret != GNUTLS_E_AGAIN) { - print("gnutls returned with: %s - %s", - gnutls_strerror_name(ret), - gnutls_strerror(ret)); - if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) - || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) - print("Also received alert: %s", - gnutls_alert_get_name - (gnutls_alert_get(client))); - print("last out: %s", - SSL_GNUTLS_PRINT_HANDSHAKE_STATUS - (gnutls_handshake_get_last_out(client))); - print("last in: %s", - SSL_GNUTLS_PRINT_HANDSHAKE_STATUS - (gnutls_handshake_get_last_in(client))); - } - - if (gnutls_error_is_fatal(ret)) { - print("yarrr this be an error!"); - exit(1); - } - - } - if (ret == GNUTLS_E_SUCCESS) { - done = 1; - //print("Handshake successful in %u handshake calls!", count); - ecore_main_loop_quit(); - } - - return ECORE_CALLBACK_RENEW; -} - -int main(void) -{ - /* credentials */ - gnutls_anon_client_credentials_t c_anoncred; - gnutls_certificate_credentials_t c_certcred; - - gnutls_session_t client; - int sd, i; - - /* General init. */ - global_init(); - ecore_init(); -// gnutls_global_set_log_function (tls_log_func); -// gnutls_global_set_log_level (6); - - /* Init client */ - gnutls_anon_allocate_client_credentials(&c_anoncred); - gnutls_certificate_allocate_credentials(&c_certcred); - - - for (i = 0; i < 5; i++) { - - gnutls_init(&client, GNUTLS_CLIENT); - /* set very specific priorities */ - - gnutls_handshake_set_timeout(client, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); - - gnutls_priority_set_direct(client, "NORMAL:+ANON-DH", - NULL); - gnutls_credentials_set(client, GNUTLS_CRD_ANON, - c_anoncred); - gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, - c_certcred); - gnutls_server_name_set(client, GNUTLS_NAME_DNS, - "localhost", strlen("localhost")); - - /* connect to the peer - */ - sd = tcp_connect(); - - /* associate gnutls with socket */ - gnutls_transport_set_int(client, sd); - /* add a callback for data being available for send/receive on socket */ - if (!ecore_main_fd_handler_add - (sd, ECORE_FD_READ | ECORE_FD_WRITE, - (Ecore_Fd_Cb) _process_data, client, NULL, NULL)) { - print("could not create fd handler!"); - exit(1); - } - /* begin main loop */ - ecore_main_loop_begin(); - - gnutls_bye(client, GNUTLS_SHUT_RDWR); - - gnutls_deinit(client); - - tcp_close(sd); - } - - gnutls_anon_free_client_credentials(c_anoncred); - gnutls_certificate_free_credentials(c_certcred); - - return 0; -} |