eolian_cxx: initial version of the EFL C++ Bindings Generator.

Summary:
This patch adds 'eolian_cxx' -- a C++ bindings generator --
to the EFL tree. Eolian Cxx uses Eolian API to read .eo files and generate
.eo.hh. It relies/depends on Eo Cxx and Eina Cxx (both non-generated
bindings).

src/bin/eolian_cxx: The eolian_cxx program.
src/lib/eolian_cxx: A header-only library that implements the C++ code
generation that binds the .eo classes.

=Examples=

src/examples/eolian_cxx/eolian_cxx_simple_01.cc: The simplest example,
it just uses some "dummy" generated C++ classes.

src/examples/eolian_cxx/eolian_cxx_inherit_01.cc: Illustrates how
pure C++ classes inherit from .eo generated classes.

src/examples/evas/evas_cxx_rectangle.cc: More realistic example using
the generated bindings Evas Cxx. Still a bit shallow because we don't
have full fledged .eo descriptions yet, but will be improved.

=Important=

The generated code is not supported and not a stable API/ABI. It is
here to gather people interest and get review before we set things in
stone for release 1.11.

@feature

Reviewers: cedric, smohanty, raster, stefan_schmidt

CC: felipealmeida, JackDanielZ, cedric, stefan

Differential Revision: https://phab.enlightenment.org/D805

Signed-off-by: Cedric Bail <cedric.bail@free.fr>
This commit is contained in:
Savio Sena 2014-05-03 00:55:51 +02:00 committed by Cedric Bail
parent 64c6c63725
commit 46b6e8a563
70 changed files with 4757 additions and 12 deletions

2
.gitignore vendored
View File

@ -31,6 +31,8 @@ tags
*.eo.c
*.eo.h
*.eo.legacy.h
*.eo.hh
.dir-locals.el
/efl-*-doc.tar.bz2
/ar-lib
/stamp-h1

View File

@ -122,7 +122,9 @@ pkgconfig_DATA += \
pc/eina.pc \
pc/eina-cxx.pc \
pc/eo.pc \
pc/eo-cxx.pc \
pc/eolian.pc \
pc/eolian-cxx.pc \
pc/eet.pc \
pc/evas.pc \
pc/ecore.pc \
@ -144,7 +146,8 @@ pc/efreet-trash.pc \
pc/edje.pc \
pc/emotion.pc \
pc/ethumb.pc \
pc/ethumb_client.pc
pc/ethumb_client.pc \
pc/evas-cxx.pc
if BUILD_ENGINE_SOFTWARE_X11
pkgconfig_DATA += pc/evas-software-x11.pc
@ -263,6 +266,36 @@ eolian_cmakeconfig_DATA = \
cmakeconfig/EolianConfig.cmake \
cmakeconfig/EolianConfigVersion.cmake
eolian_cxx_cmakeconfigdir = $(libdir)/cmake/EolianCxx/
eolian_cxx_cmakeconfig_DATA = \
cmakeconfig/EolianCxxConfig.cmake \
cmakeconfig/EolianCxxConfigVersion.cmake
eina_cxx_cmakeconfigdir = $(libdir)/cmake/EinaCxx/
eina_cxx_cmakeconfig_DATA = \
cmakeconfig/EinaCxxConfig.cmake \
cmakeconfig/EinaCxxConfigVersion.cmake
eo_cxx_cmakeconfigdir = $(libdir)/cmake/EoCxx/
eo_cxx_cmakeconfig_DATA = \
cmakeconfig/EoCxxConfig.cmake \
cmakeconfig/EoCxxConfigVersion.cmake
ecore_cxx_cmakeconfigdir = $(libdir)/cmake/EcoreCxx/
ecore_cxx_cmakeconfig_DATA = \
cmakeconfig/EcoreCxxConfig.cmake \
cmakeconfig/EcoreCxxConfigVersion.cmake
evas_cxx_cmakeconfigdir = $(libdir)/cmake/EvasCxx/
evas_cxx_cmakeconfig_DATA = \
cmakeconfig/EvasCxxConfig.cmake \
cmakeconfig/EvasCxxConfigVersion.cmake
eet_cxx_cmakeconfigdir = $(libdir)/cmake/EetCxx/
eet_cxx_cmakeconfig_DATA = \
cmakeconfig/EetCxxConfig.cmake \
cmakeconfig/EetCxxConfigVersion.cmake
eet_cmakeconfigdir = $(libdir)/cmake/Eet/
eet_cmakeconfig_DATA = \
cmakeconfig/EetConfig.cmake \

View File

@ -0,0 +1,66 @@
# - Try to find ecore_cxx
# Once done this will define
#
# ECORE_CXX_FOUND - System has ecore_cxx
# ECORE_CXX_INCLUDE_DIRS - The ecore_cxx include directories
# ECORE_CXX_LIBRARIES - The libraries needed to use ecore_cxx
# ECORE_CXX_DEFINITIONS - Compiler switches required for using ecore_cxx
#
# When the COMPONENTS keyword was passed to find_package(),
# the following variables are defined for additional Ecore_Cxx modules
# such as Evas, X, Imf, Imf_Evas.
#
# ECORE_CXX_*_FOUND - System has ecore_cxx *
# ECORE_CXX_*_INCLUDE_DIRS - The ecore_cxx include directories
# ECORE_CXX_*_LIBRARIES - The libraries needed to use ecore_cxx
# ECORE_CXX_*_DEFINITIONS - Compiler switches required for using ecore_cxx * module.
set(MY_PKG ecore_cxx)
find_package(PkgConfig)
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
# "QUIET" was introduced in 2.8.2
set(_QUIET QUIET)
endif ()
pkg_check_modules(PC_LIBECORE_CXX ${_QUIET} ${MY_PKG})
find_library(ECORE_CXX_LIBRARY
NAMES ${PC_LIBECORE_CXX_LIBRARIES}
HINTS ${PC_LIBECORE_CXX_LIBDIR} ${PC_LIBECORE_CXX_LIBRARY_DIRS} )
set(ECORE_CXX_DEFINITIONS ${PC_LIBECORE_CXX_CFLAGS_OTHER})
set(ECORE_CXX_LIBRARIES ${ECORE_CXX_LIBRARY})
set(ECORE_CXX_INCLUDE_DIRS ${PC_LIBECORE_CXX_INCLUDE_DIRS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set ECORE_CXX_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
ECORE_CXX_LIBRARIES ECORE_CXX_INCLUDE_DIRS)
mark_as_advanced(ECORE_CXX_INCLUDE_DIRS ECORE_CXX_LIBRARY ECORE_CXX_LIBRARIES ECORE_CXX_DEFINITIONS)
if (Ecore_Cxx_FIND_COMPONENTS)
foreach(_component ${Ecore_Cxx_FIND_COMPONENTS})
string(TOUPPER ${_component} _COMPONENT)
string(TOLOWER ${_component} _component)
string(REGEX REPLACE "_" "-" _MODULE_PKGNAME "ecore_cxx-${_component}")
pkg_check_modules(PC_LIBECORE_CXX_${_COMPONENT} ${_QUIET} ${_MODULE_PKGNAME})
find_library(ECORE_CXX_${_COMPONENT}_LIBRARY
NAMES ${PC_LIBECORE_CXX_${_COMPONENT}_LIBRARIES}
HINTS ${PC_LIBECORE_CXX_${_COMPONENT}_LIBDIR}
${PC_LIBECORE_CXX_${_COMPONENT}_LIBRARY_DIRS})
set(ECORE_CXX_${_COMPONENT}_DEFINITIONS ${PC_LIBECORE_CXX_${_COMPONENT}_CFLAGS_OTHER})
set(ECORE_CXX_${_COMPONENT}_LIBRARIES ${ECORE_CXX_${_COMPONENT}_LIBRARY})
set(ECORE_CXX_${_COMPONENT}_INCLUDE_DIRS ${PC_LIBECORE_CXX_${_COMPONENT}_INCLUDE_DIRS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set ECORE_CXX_*_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(ecore_cxx_${_component} DEFAULT_MSG
ECORE_CXX_${_COMPONENT}_LIBRARIES ECORE_CXX_${_COMPONENT}_INCLUDE_DIRS)
endforeach(_component)
endif(Ecore_Cxx_FIND_COMPONENTS)

View File

@ -0,0 +1,30 @@
# - Try to find eet
# Once done this will define
# EET_CXX_FOUND - System has eet
# EET_CXX_INCLUDE_DIRS - The eet include directories
# EET_CXX_LIBRARIES - The libraries needed to use eet
# EET_CXX_DEFINITIONS - Compiler switches required for using eet
set(MY_PKG eet_cxx)
find_package(PkgConfig)
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
# "QUIET" was introduced in 2.8.2
set(_QUIET QUIET)
endif ()
pkg_check_modules(PC_EET_CXX ${_QUIET} ${MY_PKG})
find_library(EET_CXX_LIBRARY
NAMES ${PC_EET_CXX_LIBRARIES}
HINTS ${PC_EET_CXX_LIBDIR} ${PC_EET_CXX_LIBRARY_DIRS} )
set(EET_CXX_DEFINITIONS ${PC_EET_CXX_CFLAGS_OTHER})
set(EET_CXX_LIBRARIES ${EET_CXX_LIBRARY})
set(EET_CXX_INCLUDE_DIRS ${PC_EET_CXX_INCLUDE_DIRS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set EET_CXX_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
EET_CXX_LIBRARIES EET_CXX_INCLUDE_DIRS)
mark_as_advanced(EET_CXX_INCLUDE_DIRS EET_CXX_LIBRARY EET_CXX_LIBRARIES EET_CXX_DEFINITIONS)

View File

@ -0,0 +1,30 @@
# - Try to find eina
# Once done this will define
# EINA_CXX_FOUND - System has eina
# EINA_CXX_INCLUDE_DIRS - The eina include directories
# EINA_CXX_LIBRARIES - The libraries needed to use eina
# EINA_CXX_DEFINITIONS - Compiler switches required for using eina
set(MY_PKG eina_cxx)
find_package(PkgConfig)
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
# "QUIET" was introduced in 2.8.2
set(_QUIET QUIET)
endif ()
pkg_check_modules(PC_EINA_CXX ${_QUIET} ${MY_PKG})
find_library(EINA_CXX_LIBRARY
NAMES ${PC_EINA_CXX_LIBRARIES}
HINTS ${PC_EINA_CXX_LIBDIR} ${PC_EINA_CXX_LIBRARY_DIRS} )
set(EINA_CXX_DEFINITIONS ${PC_EINA_CXX_CFLAGS_OTHER})
set(EINA_CXX_LIBRARIES ${EINA_CXX_LIBRARY})
set(EINA_CXX_INCLUDE_DIRS ${PC_EINA_CXX_INCLUDE_DIRS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set EINA_CXX_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
EINA_CXX_LIBRARIES EINA_CXX_INCLUDE_DIRS)
mark_as_advanced(EINA_CXX_INCLUDE_DIRS EINA_CXX_LIBRARY EINA_CXX_LIBRARIES EINA_CXX_DEFINITIONS)

View File

@ -0,0 +1,30 @@
# - Try to find eo
# Once done this will define
# EO_CXX_FOUND - System has eo
# EO_CXX_INCLUDE_DIRS - The eo include directories
# EO_CXX_LIBRARIES - The libraries needed to use eo
# EO_CXX_DEFINITIONS - Compiler switches required for using eo
set(MY_PKG eo_cxx)
find_package(PkgConfig)
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
# "QUIET" was introduced in 2.8.2
set(_QUIET QUIET)
endif ()
pkg_check_modules(PC_EO_CXX ${_QUIET} ${MY_PKG})
find_library(EO_CXX_LIBRARY
NAMES ${PC_EO_CXX_LIBRARIES}
HINTS ${PC_EO_CXX_LIBDIR} ${PC_EO_CXX_LIBRARY_DIRS} )
set(EO_CXX_DEFINITIONS ${PC_EO_CXX_CFLAGS_OTHER})
set(EO_CXX_LIBRARIES ${EO_CXX_LIBRARY})
set(EO_CXX_INCLUDE_DIRS ${PC_EO_CXX_INCLUDE_DIRS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set EO_CXX_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
EO_CXX_LIBRARIES EO_CXX_INCLUDE_DIRS)
mark_as_advanced(EO_CXX_INCLUDE_DIRS EO_CXX_LIBRARY EO_CXX_LIBRARIES EO_CXX_DEFINITIONS)

View File

@ -0,0 +1,30 @@
# - Try to find eolian
# Once done this will define
# EOLIAN_CXX_FOUND - System has eolian
# EOLIAN_CXX_INCLUDE_DIRS - The eolian include directories
# EOLIAN_CXX_LIBRARIES - The libraries needed to use eolian
# EOLIAN_CXX_DEFINITIONS - Compiler switches required for using eolian
set(MY_PKG eolian_cxx)
find_package(PkgConfig)
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
# "QUIET" was introduced in 2.8.2
set(_QUIET QUIET)
endif ()
pkg_check_modules(PC_EOLIAN_CXX ${_QUIET} ${MY_PKG})
find_library(EOLIAN_CXX_LIBRARY
NAMES ${PC_EOLIAN_CXX_LIBRARIES}
HINTS ${PC_EOLIAN_CXX_LIBDIR} ${PC_EOLIAN_CXX_LIBRARY_DIRS} )
set(EOLIAN_CXX_DEFINITIONS ${PC_EOLIAN_CXX_CFLAGS_OTHER})
set(EOLIAN_CXX_LIBRARIES ${EOLIAN_CXX_LIBRARY})
set(EOLIAN_CXX_INCLUDE_DIRS ${PC_EOLIAN_CXX_INCLUDE_DIRS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set EOLIAN_CXX_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
EOLIAN_CXX_LIBRARIES EOLIAN_CXX_INCLUDE_DIRS)
mark_as_advanced(EOLIAN_CXX_INCLUDE_DIRS EOLIAN_CXX_LIBRARY EOLIAN_CXX_LIBRARIES EOLIAN_CXX_DEFINITIONS)

View File

@ -0,0 +1,30 @@
# - Try to find evas
# Once done this will define
# EVAS_CXX_FOUND - System has evas
# EVAS_CXX_INCLUDE_DIRS - The evas include directories
# EVAS_CXX_LIBRARIES - The libraries needed to use evas
# EVAS_CXX_DEFINITIONS - Compiler switches required for using evas
set(MY_PKG evas_cxx)
find_package(PkgConfig)
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
# "QUIET" was introduced in 2.8.2
set(_QUIET QUIET)
endif ()
pkg_check_modules(PC_EVAS_CXX ${_QUIET} ${MY_PKG})
find_library(EVAS_CXX_LIBRARY
NAMES ${PC_EVAS_CXX_LIBRARIES}
HINTS ${PC_EVAS_CXX_LIBDIR} ${PC_EVAS_CXX_LIBRARY_DIRS} )
set(EVAS_CXX_DEFINITIONS ${PC_EVAS_CXX_CFLAGS_OTHER})
set(EVAS_CXX_LIBRARIES ${EVAS_CXX_LIBRARY})
set(EVAS_CXX_INCLUDE_DIRS ${PC_EVAS_CXX_INCLUDE_DIRS})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set EVAS_CXX_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(${MY_PKG} DEFAULT_MSG
EVAS_CXX_LIBRARIES EVAS_CXX_INCLUDE_DIRS)
mark_as_advanced(EVAS_CXX_INCLUDE_DIRS EVAS_CXX_LIBRARY EVAS_CXX_LIBRARIES EVAS_CXX_DEFINITIONS)

View File

@ -146,7 +146,7 @@ AC_SUBST(dbusservicedir)
efl_deprecated_option="no"
EFL_WITH_BIN([edje], [edje-cc])
EFL_WITH_BIN([eolian], [eolian-gen])
EFL_WITH_BIN([eolian_cxx], [eolian-cxx])
#### Default values
@ -1057,6 +1057,7 @@ EFL_LIB_START([Eolian])
### Default values
### Additional options to configure
EFL_ADD_FEATURE([EOLIAN], [cxx], [${have_cxx11}])
### Checks for programs
@ -4110,6 +4111,7 @@ src/examples/ephysics/Makefile
src/examples/edje/Makefile
src/examples/emotion/Makefile
src/examples/ethumb_client/Makefile
src/examples/eolian_cxx/Makefile
src/lib/eina/eina_config.h
src/lib/ecore_x/ecore_x_version.h
src/lib/efl/Efl_Config.h
@ -4121,7 +4123,9 @@ pc/eina-cxx.pc
pc/eet.pc
pc/eet-cxx.pc
pc/eo.pc
pc/eo-cxx.pc
pc/eolian.pc
pc/eolian-cxx.pc
pc/evas-fb.pc
pc/evas-opengl-x11.pc
pc/evas-opengl-sdl.pc
@ -4136,6 +4140,7 @@ pc/evas-wayland-shm.pc
pc/evas-wayland-egl.pc
pc/evas-drm.pc
pc/evas.pc
pc/evas-cxx.pc
pc/ecore.pc
pc/ecore-con.pc
pc/ecore-ipc.pc
@ -4181,6 +4186,18 @@ cmakeconfig/EoConfig.cmake
cmakeconfig/EoConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EolianConfig.cmake
cmakeconfig/EolianConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EolianCxxConfig.cmake
cmakeconfig/EolianCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EinaCxxConfig.cmake
cmakeconfig/EinaCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EoCxxConfig.cmake
cmakeconfig/EoCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EcoreCxxConfig.cmake
cmakeconfig/EcoreCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EvasCxxConfig.cmake
cmakeconfig/EvasCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EetCxxConfig.cmake
cmakeconfig/EetCxxConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EetConfig.cmake
cmakeconfig/EetConfigVersion.cmake:cmakeconfig/EFLConfigVersion.cmake.in
cmakeconfig/EvasConfig.cmake

4
pc/.gitignore vendored
View File

@ -52,3 +52,7 @@
/evas.pc
/evil.pc
/eolian.pc
/eolian-cxx.pc
/eo-cxx.pc
/evas-cxx.pc
/ecore-audio-cxx.pc.in

View File

@ -9,4 +9,4 @@ Version: @VERSION@
Requires.private: @requirements_pc_eet@
Libs: -L${libdir} -leet
Libs.private: @requirements_libs_eet@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eet-@VMAJ@ -I${includedir}/efl-@VMAJ@ -I${includedir}/eet_cxx-@VMAJ@ -I${includedir}/eet_cxx-@VMAJ@/eet_cxx
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eet-@VMAJ@ -I${includedir}/efl-@VMAJ@ -I${includedir}/eet-cxx-@VMAJ@ -I${includedir}/eet-cxx-@VMAJ@/eet-cxx

View File

@ -9,4 +9,4 @@ Requires.private: @requirements_pc_eina@
Version: @VERSION@
Libs: -L${libdir} -leina @requirements_public_libs_eina@
Libs.private: @requirements_libs_eina@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eina-@VMAJ@ -I${includedir}/eina-@VMAJ@/eina -I${includedir}/eina_cxx-@VMAJ@ -I${includedir}/eina_cxx-@VMAJ@/eina_cxx
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eina-@VMAJ@ -I${includedir}/eina-@VMAJ@/eina -I${includedir}/eina-cxx-@VMAJ@ -I${includedir}/eina-cxx-@VMAJ@/eina-cxx

12
pc/eo-cxx.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Eo C++
Description: C++ bindings for EFL's generic object system.
Version: @PACKAGE_VERSION@
Requires.private: @requirements_pc_eo@
Libs.private: @requirements_libs_eo@
Libs: -L${libdir} -leo
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eo-@VMAJ@ -I${includedir}/eo-cxx-@VMAJ@

12
pc/eolian-cxx.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Eolian C++
Description: EFL's C++ bindings generator.
Version: @VERSION@
Require.private: @requirements_pc_eolian_cxx@
Libs: -L${libdir}
Libs.private: @requirements_libs_eolian_cxx@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eolian-cxx-@VMAJ@

15
pc/evas-cxx.pc.in Normal file
View File

@ -0,0 +1,15 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
eoincludedir=@datarootdir@/eolian/include
eolian_flags=-I${eoincludedir}/evas-cxx-@VMAJ@
Name: evas
Description: Evas C++ Bindings
Requires.private: @requirements_pc_evas@
Version: @VERSION@
Libs: -L${libdir} -levas
Libs.private: @requirements_libs_evas@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/evas-@VMAJ@ -I${includedir}/evas-cxx-@VMAJ@

View File

@ -56,7 +56,9 @@ include Makefile_Ecore_IMF.am
include Makefile_Ecore_IMF_Evas.am
include Makefile_Ecore_Evas.am
include Makefile_Ecore_Audio.am
include Makefile_Ecore_Audio_Cxx.am
include Makefile_Ecore_Avahi.am
include Makefile_Evas_Cxx.am
include Makefile_Embryo.am
include Makefile_Eio.am
include Makefile_Eldbus.am
@ -68,7 +70,10 @@ include Makefile_Emotion.am
include Makefile_Ethumb.am
include Makefile_Ethumb_Client.am
include Makefile_Eolian_Cxx.am
include Makefile_Eina_Cxx.am
include Makefile_Eo_Cxx.am
include Makefile_Edje_Cxx.am
.PHONY: benchmark examples
@ -97,7 +102,8 @@ examples/eldbus \
examples/ephysics \
examples/edje \
examples/emotion \
examples/ethumb_client
examples/ethumb_client \
examples/eolian_cxx
if ALWAYS_BUILD_EXAMPLES
SUBDIRS += . $(EXAMPLES_SUBDIRS)
endif

View File

@ -0,0 +1,58 @@
if HAVE_CXX11
### Generated headers
generated_ecore_audio_cxx_bindings = \
lib/ecore_audio/ecore_audio.eo.hh \
lib/ecore_audio/ecore_audio_in.eo.hh \
lib/ecore_audio/ecore_audio_out.eo.hh \
lib/ecore_audio/ecore_audio_in_sndfile.eo.hh \
lib/ecore_audio/ecore_audio_out_sndfile.eo.hh \
lib/ecore_audio/ecore_audio_out_pulse.eo.hh \
lib/ecore_audio/ecore_audio_in_tone.eo.hh
BUILT_SOURCES += \
lib/ecore_audio/Ecore_Audio.hh \
$(generated_ecore_audio_cxx_bindings)
lib/ecore_audio/Ecore_Audio.hh:
@echo -e "#ifndef EFL_CXX_ECORE_AUDIO_HH\n#define EFL_CXX_ECORE_AUDIO_HH\n" > $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh
@echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh
@for i in $(generated_ecore_audio_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh; done
@echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/ecore_audio/Ecore_Audio.hh
installed_ecoreaudiocxxmainheadersdir = $(includedir)/ecore-audio-cxx-@VMAJ@
dist_installed_ecoreaudiocxxmainheaders_DATA = \
lib/ecore_audio/Ecore_Audio.hh \
$(generated_ecore_audio_cxx_bindings)
### Unit tests
if EFL_ENABLE_TESTS
check_PROGRAMS += tests/ecore_audio_cxx/cxx_compile_test
TESTS += tests/ecore_audio_cxx/cxx_compile_test
tests_ecore_audio_cxx_cxx_compile_test_SOURCES = tests/ecore_audio_cxx/cxx_compile_test.cc
tests_ecore_audio_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/ecore_audio \
-I$(top_builddir)/src/lib/ecore_audio \
-I$(top_srcdir)/src/lib/ecore \
-I$(top_builddir)/src/lib/ecore \
-I$(top_srcdir)/src/lib/eo \
-I$(top_builddir)/src/lib/eo \
-I$(top_srcdir)/src/bindings/eo_cxx \
-I$(top_builddir)/src/bindings/eo_cxx \
-I$(top_srcdir)/src/bindings/ecore_cxx \
-I$(top_builddir)/src/bindings/ecore_cxx \
-I$(top_srcdir)/src/bindings/eina_cxx \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ecore_audio_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/ecore_audio_cxx\" \
@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
tests_ecore_audio_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
tests_ecore_audio_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
endif
endif

View File

@ -1,17 +1,43 @@
### Library
installed_ecorecxxmainheadersdir = $(includedir)/ecore_cxx-@VMAJ@
dist_installed_ecorecxxmainheaders_DATA = \
bindings/ecore_cxx/Ecore.hh
installed_ecorecxxmainheadersdir = $(includedir)/ecore-cxx-@VMAJ@
dist_installed_ecorecxxmainheaders_DATA = bindings/ecore_cxx/Ecore.hh
if HAVE_CXX11
generated_ecore_cxx_bindings = \
lib/ecore/ecore_poll.eo.hh \
lib/ecore/ecore_job.eo.hh \
lib/ecore/ecore_idler.eo.hh \
lib/ecore/ecore_idle_exiter.eo.hh \
lib/ecore/ecore_animator.eo.hh \
lib/ecore/ecore_parent.eo.hh
BUILT_SOURCES += \
lib/ecore/Ecore.eo.hh \
$(generated_ecore_cxx_bindings)
installed_ecorecxxheadersdir = $(includedir)/ecore-cxx-@VMAJ@
dist_installed_ecorecxxheaders_DATA = \
lib/ecore/Ecore.eo.hh \
$(generated_ecore_cxx_bindings)
lib/ecore/Ecore.eo.hh:
@echo -e "#ifndef EFL_CXX_ECORE_HH\n#define EFL_CXX_ECORE_HH\n" > $(top_builddir)/src/lib/ecore/Ecore.eo.hh
@echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh
@for i in $(generated_ecore_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh; done
@echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh
endif
### Unit tests
if EFL_ENABLE_TESTS
if HAVE_CXX11
check_PROGRAMS += tests/ecore_cxx/ecore_cxx_suite
TESTS += tests/ecore_cxx/ecore_cxx_suite
check_PROGRAMS += tests/ecore_cxx/ecore_cxx_suite tests/ecore_cxx/cxx_compile_test
TESTS += tests/ecore_cxx/ecore_cxx_suite tests/ecore_cxx/cxx_compile_test
tests_ecore_cxx_ecore_cxx_suite_SOURCES = \
tests/ecore_cxx/ecore_cxx_suite.cc \
@ -20,6 +46,7 @@ tests/ecore_cxx/ecore_cxx_test_safe_call.cc
tests_ecore_cxx_ecore_cxx_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bindings/ecore_cxx \
-I$(top_srcdir)/src/bindings/eina_cxx \
-I$(top_srcdir)/src/bindings/eo_cxx \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ecore_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/ecore_cxx\" \
@CHECK_CFLAGS@ \
@ -32,5 +59,16 @@ tests_ecore_cxx_ecore_cxx_suite_LDADD = \
tests_ecore_cxx_ecore_cxx_suite_DEPENDENCIES = \
@USE_ECORE_INTERNAL_LIBS@
tests_ecore_cxx_cxx_compile_test_SOURCES = tests/ecore_cxx/cxx_compile_test.cc
tests_ecore_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/bindings/ecore_cxx \
-I$(top_srcdir)/src/bindings/eina_cxx \
-I$(top_srcdir)/src/bindings/eo_cxx \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ecore_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/ecore_cxx\" \
@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
tests_ecore_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
tests_ecore_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
endif
endif

62
src/Makefile_Edje_Cxx.am Normal file
View File

@ -0,0 +1,62 @@
if HAVE_CXX11
### Generated headers
generated_edje_cxx_bindings = \
lib/edje/edje.eo.hh \
lib/edje/edje_edit.eo.hh
BUILT_SOURCES += \
lib/edje/Edje.hh \
$(generated_edje_cxx_bindings)
EXTRA_DIST += \
lib/edje/Edje.hh \
$(edje_cxx_bindngs)
installed_edjecxxmainheadersdir = $(includedir)/edje-cxx-@VMAJ@/
dist_installed_edjecxxmainheaders_DATA = \
lib/edje/Edje.hh \
$(generated_edje_cxx_bindings)
lib/edje/Edje.hh:
@echo -e "#ifndef EFL_CXX_EDJE_HH\n#define EFL_CXX_EDJE_HH\n" > $(top_builddir)/src/lib/edje/Edje.hh
@echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/edje/Edje.hh
@for i in $(generated_edje_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/edje/Edje.hh; done
@echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/edje/Edje.hh
### Unit tests
if EFL_ENABLE_TESTS
check_PROGRAMS += tests/edje_cxx/cxx_compile_test
TESTS += tests/edje_cxx/cxx_compile_test
tests_edje_cxx_cxx_compile_test_SOURCES = tests/edje_cxx/cxx_compile_test.cc
tests_edje_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/edje \
-I$(top_builddir)/src/lib/edje \
-I$(top_srcdir)/src/lib/evas \
-I$(top_builddir)/src/lib/evas \
-I$(top_srcdir)/src/lib/evas/canvas \
-I$(top_builddir)/src/lib/evas/canvas \
-I$(top_srcdir)/src/lib/ecore \
-I$(top_builddir)/src/lib/ecore \
-I$(top_srcdir)/src/lib/eo \
-I$(top_builddir)/src/lib/eo \
-I$(top_srcdir)/src/bindings/eo_cxx \
-I$(top_builddir)/src/bindings/eo_cxx \
-I$(top_srcdir)/src/bindings/ecore_cxx \
-I$(top_builddir)/src/bindings/ecore_cxx \
-I$(top_srcdir)/src/bindings/eina_cxx \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/edje_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/edje_cxx\" \
@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
tests_edje_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
tests_edje_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
endif
endif

View File

@ -1,10 +1,10 @@
### Library
installed_eetcxxmainheadersdir = $(includedir)/eet_cxx-@VMAJ@
installed_eetcxxmainheadersdir = $(includedir)/eet-cxx-@VMAJ@
dist_installed_eetcxxmainheaders_DATA = bindings/eet_cxx/Eet.hh
installed_eetcxxheadersdir = $(includedir)/eet_cxx-@VMAJ@/eet_cxx
installed_eetcxxheadersdir = $(includedir)/eet-cxx-@VMAJ@/eet-cxx
dist_installed_eetcxxheaders_DATA = \
bindings/eet_cxx/eet_composite.hh \
bindings/eet_cxx/eet_fold.hh \

16
src/Makefile_Eo_Cxx.am Normal file
View File

@ -0,0 +1,16 @@
### Library
installed_eocxxmainheadersdir = $(includedir)/eo-cxx-@VMAJ@/
dist_installed_eocxxmainheaders_DATA = \
bindings/eo_cxx/Eo.hh
installed_eocxxheadersdir = $(includedir)/eo-cxx-@VMAJ@/
dist_installed_eocxxheaders_DATA = \
bindings/eo_cxx/eo_base.hh \
bindings/eo_cxx/eo_init.hh \
bindings/eo_cxx/eo_wref.hh \
bindings/eo_cxx/eo_inherit.hh \
bindings/eo_cxx/eo_ops.hh \
bindings/eo_cxx/eo_private.hh \
bindings/eo_cxx/eo_inherit_bindings.hh

View File

@ -0,0 +1,46 @@
### Binary
bin_PROGRAMS += \
bin/eolian_cxx/eolian_cxx
bin_eolian_cxx_eolian_cxx_SOURCES = \
bin/eolian_cxx/comments.cc \
bin/eolian_cxx/comments.hh \
bin/eolian_cxx/convert.cc \
bin/eolian_cxx/convert.hh \
bin/eolian_cxx/eo_read.h \
bin/eolian_cxx/safe_strings.hh \
bin/eolian_cxx/eolian_cxx.cc
bin_eolian_cxx_eolian_cxx_CFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I$(top_builddir)/src/lib/eo \
-I$(top_srcdir)/src/lib/eo \
-I$(top_builddir)/src/lib/eina \
-I$(top_srcdir)/src/lib/eina \
-I$(top_builddir)/src/lib/eolian \
-I$(top_srcdir)/src/lib/eolian
bin_eolian_cxx_eolian_cxx_CXXFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I$(top_builddir)/src/lib/eo \
-I$(top_srcdir)/src/lib/eo \
-I$(top_builddir)/src/lib/eina \
-I$(top_srcdir)/src/lib/eina \
-I$(top_builddir)/src/lib/eolian \
-I$(top_srcdir)/src/lib/eolian \
-I$(top_builddir)/src/bindings/eina_cxx \
-I$(top_srcdir)/src/bindings/eina_cxx \
-I$(top_builddir)/src/lib/eolian_cxx \
-I$(top_srcdir)/src/lib/eolian_cxx
bin_eolian_cxx_eolian_cxx_LDADD = \
@USE_EOLIAN_LIBS@
bin_eolian_cxx_eolian_cxx_DEPENDENCIES = \
@USE_EOLIAN_INTERNAL_LIBS@
include Makefile_Eolian_Cxx_Helper.am
CLEANFILES += $(BUILT_SOURCES)

View File

@ -0,0 +1,19 @@
if HAVE_EOLIAN_CXX
EOLIAN_CXX = @eolian_cxx@
_EOLIAN_CXX_DEP = @eolian_cxx@
else
EOLIAN_CXX = EFL_RUN_IN_TREE=1 $(top_builddir)/src/bin/eolian_cxx/eolian_cxx${EXEEXT}
_EOLIAN_CXX_DEP = bin/eolian_cxx/eolian_cxx${EXEEXT}
endif
AM_V_EOLCXX = $(am__v_EOLCXX_@AM_V@)
am__v_EOLCXX_ = $(am__v_EOLCXX_@AM_DEFAULT_V@)
am__v_EOLCXX_0 = @echo " EOLCXX " $@;
SUFFIXES += .eo.hh
%.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I./$< -o $@
CLEANFILES += $(BUILT_SOURCES)

76
src/Makefile_Evas_Cxx.am Normal file
View File

@ -0,0 +1,76 @@
if HAVE_CXX11
### Generated headers
generated_evas_canvas_cxx_bindings = \
lib/evas/canvas/evas_line.eo.hh \
lib/evas/canvas/evas_polygon.eo.hh \
lib/evas/canvas/evas_rectangle.eo.hh \
lib/evas/canvas/evas_text.eo.hh \
lib/evas/canvas/evas_textblock.eo.hh \
lib/evas/canvas/evas_textgrid.eo.hh \
lib/evas/canvas/evas_signal_interface.eo.hh \
lib/evas/canvas/evas_smart.eo.hh \
lib/evas/canvas/evas_smart_clipped.eo.hh \
lib/evas/canvas/evas_table.eo.hh \
lib/evas/canvas/evas_common_interface.eo.hh \
lib/evas/canvas/evas_object.eo.hh \
lib/evas/canvas/evas.eo.hh \
lib/evas/canvas/evas_grid.eo.hh \
lib/evas/canvas/evas_image.eo.hh \
lib/evas/canvas/evas_out.eo.hh \
lib/evas/canvas/evas_draggable_interface.eo.hh \
lib/evas/canvas/evas_clickable_interface.eo.hh \
lib/evas/canvas/evas_scrollable_interface.eo.hh \
lib/evas/canvas/evas_selectable_interface.eo.hh \
lib/evas/canvas/evas_zoomable_interface.eo.hh \
lib/evas/canvas/evas_box.eo.hh
BUILT_SOURCES += lib/evas/Evas.hh $(generated_evas_canvas_cxx_bindings)
installed_evascanvasmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/
dist_installed_evascanvasmainheaders_DATA = lib/evas/Evas.hh
installed_evascanvasmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/canvas
dist_installed_evascanvasmainheaders_DATA = $(generated_evas_canvas_cxx_bindings)
lib/evas/Evas.hh:
@echo -e "#ifndef EFL_CXX_EVAS_HH\n#define EFL_CXX_EVAS_HH\n" > $(top_builddir)/src/lib/evas/Evas.hh
@echo -e "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/evas/Evas.hh
@for i in $(generated_evas_canvas_cxx_bindings); do echo "#include <canvas/$$(basename $$i)>" >> $(top_builddir)/src/lib/evas/Evas.hh; done
@echo -e "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/evas/Evas.hh
### Unit tests
if EFL_ENABLE_TESTS
check_PROGRAMS += tests/evas_cxx/cxx_compile_test
TESTS += tests/evas_cxx/cxx_compile_test
tests_evas_cxx_cxx_compile_test_SOURCES = tests/evas_cxx/cxx_compile_test.cc
tests_evas_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/edje \
-I$(top_builddir)/src/lib/edje \
-I$(top_srcdir)/src/lib/evas \
-I$(top_builddir)/src/lib/evas \
-I$(top_srcdir)/src/lib/evas/canvas \
-I$(top_builddir)/src/lib/evas/canvas \
-I$(top_srcdir)/src/lib/ecore \
-I$(top_builddir)/src/lib/ecore \
-I$(top_srcdir)/src/lib/eo \
-I$(top_builddir)/src/lib/eo \
-I$(top_srcdir)/src/bindings/eo_cxx \
-I$(top_builddir)/src/bindings/eo_cxx \
-I$(top_srcdir)/src/bindings/ecore_cxx \
-I$(top_builddir)/src/bindings/ecore_cxx \
-I$(top_srcdir)/src/bindings/eina_cxx \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/evas_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/evas_cxx\" \
@CHECK_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@
tests_evas_cxx_cxx_compile_test_LDADD = @CHECK_LIBS@ @USE_ECORE_LIBS@
tests_evas_cxx_cxx_compile_test_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@
endif
endif

1
src/bin/eolian_cxx/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/eolian_cxx

View File

@ -0,0 +1,110 @@
#include "comments.hh"
#include "safe_strings.hh"
static std::string
_comment_parameter(Eolian_Function_Parameter param)
{
Eolian_Parameter_Dir direction;
Eina_Stringshare *description;
eolian_parameter_information_get
(param, &direction, NULL, NULL, &description);
std::string doc = "@param";
if (direction == EOLIAN_IN_PARAM) doc += " ";
else if (direction == EOLIAN_OUT_PARAM) doc += "[out] ";
else if (direction == EOLIAN_INOUT_PARAM) doc += "[inout] ";
else assert(false);
doc += safe_strshare(eolian_parameter_name_get(param));
doc += " ";
doc += safe_str(description);
return doc;
}
static std::string
_comment_parameters_list(const Eina_List *params)
{
std::string doc = "";
const Eina_List *it;
void *curr;
EINA_LIST_FOREACH (params, it, curr)
{
doc += _comment_parameter
(static_cast<Eolian_Function_Parameter>(curr)) + "\n";
}
return doc;
}
static std::string
_comment_brief_and_params(Eolian_Function function,
const char *key = EOLIAN_COMMENT)
{
std::string doc = "";
std::string func = safe_str(eolian_function_description_get(function, key));
if (func != "")
{
doc += "@brief " + func + "\n\n";
}
std::string params = _comment_parameters_list(eolian_parameters_list_get(function));
if (params != "")
{
doc += params + "\n";
}
return doc;
}
static std::string
_comment_return(Eolian_Function function,
Eolian_Function_Type rettype)
{
std::string doc = "";
std::string ret = safe_str(eolian_function_return_type_get(function, rettype));
std::string comment = safe_str(eolian_function_return_comment_get(function, rettype));
if (ret != "void" && ret != "" && comment != "")
{
doc = "@return " + comment;
}
return doc;
}
namespace detail {
std::string
eolian_class_comment(const char *classname)
{
return safe_str(eolian_class_description_get(classname));
}
std::string
eolian_constructor_comment(Eolian_Function constructor)
{
return _comment_brief_and_params(constructor);
}
std::string eolian_function_comment(Eolian_Function function)
{
std::string doc = _comment_brief_and_params(function);
doc += _comment_return(function, EOLIAN_METHOD);
return doc;
}
std::string eolian_property_getter_comment(Eolian_Function property)
{
std::string doc = _comment_brief_and_params
(property, EOLIAN_COMMENT_GET);
doc += _comment_return(property, EOLIAN_PROP_GET);
return doc;
}
std::string eolian_property_setter_comment(Eolian_Function property)
{
std::string doc = _comment_brief_and_params
(property, EOLIAN_COMMENT_SET);
doc += _comment_return(property, EOLIAN_PROP_SET);
return doc;
}
} // namespace detail

View File

@ -0,0 +1,29 @@
#ifndef EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
#define EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
#include <string>
extern "C"
{
#include <Eina.h>
#include <Eolian.h>
}
#include <Eolian_Cxx.hh>
namespace detail {
std::string eolian_class_comment(const char *classname);
std::string eolian_constructor_comment(Eolian_Function constructor);
std::string eolian_function_comment(Eolian_Function function);
std::string eolian_property_getter_comment(Eolian_Function function);
std::string eolian_property_setter_comment(Eolian_Function function);
}
#endif // EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH

View File

@ -0,0 +1,304 @@
#include <vector>
#include <algorithm>
#include <cassert>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Eina.h>
#include <Eina.hh>
#include <Eo.h>
#include <Eolian.h>
#include "eo_types.hh"
#include "safe_strings.hh"
#include "comments.hh"
static std::string
_resolve_param_type(Eolian_Function_Parameter id, bool is_get)
{
Eolian_Parameter_Dir dir;
const char *type;
bool is_const;
std::string res;
eolian_parameter_information_get(id, &dir, &type, NULL, NULL);
is_const = eolian_parameter_const_attribute_get(id, is_get);
res = safe_str(type);
assert(res != "");
if (is_const) res = std::string("const ") + res;
if (dir == EOLIAN_OUT_PARAM || dir == EOLIAN_INOUT_PARAM) res += "*";
return res;
}
static efl::eolian::parameters_container_type
_get_params(const Eina_List *eolian_params, bool is_get = false)
{
const Eina_List *it;
void *curr;
if (eolian_params == NULL)
{
return efl::eolian::parameters_container_type();
}
efl::eolian::parameters_container_type list;
EINA_LIST_FOREACH (eolian_params, it, curr)
{
Eolian_Function_Parameter id =
(static_cast<Eolian_Function_Parameter>(curr));
list.push_back({
_resolve_param_type(id, is_get),
safe_strshare(eolian_parameter_name_get(id))
});
}
return list;
}
static efl::eolian::functions_container_type
_get_properties(const char *classname)
{
efl::eolian::functions_container_type container;
std::string cxx_classname = classname;
std::transform(cxx_classname.begin(), cxx_classname.end(),
cxx_classname.begin(), ::tolower);
const Eina_List *properties;
properties = eolian_class_functions_list_get(classname, EOLIAN_PROPERTY);
const Eina_List *it;
void *curr;
std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
EINA_LIST_FOREACH (properties, it, curr)
{
Eolian_Function property = static_cast<Eolian_Function>(curr);
Eolian_Function_Type type = eolian_function_type_get(property);
std::string name = safe_str(eolian_function_name_get(property));
if (type == EOLIAN_PROP_GET || type == EOLIAN_PROPERTY)
{
const Eina_List *keys_ = eolian_property_keys_list_get(property);
efl::eolian::parameters_container_type params = _get_params
(eolian_parameters_list_get(property), true);
efl::eolian::eo_function getter;
getter.type = efl::eolian::eo_function::regular_;
getter.name = name + "_get";
getter.impl = (prefix != "" ? prefix : cxx_classname) + "_" + getter.name;
std::string ret = safe_str
(eolian_function_return_type_get(property, EOLIAN_PROP_GET));
if (ret == "") ret = "void";
// if the getter has a single parameter and void return
// we translate it to a getter with no parameters that
// returns its type.
if ((ret == "void") && params.size() == 1)
{
getter.ret = params[0].type;
getter.params.clear();
}
else // otherwise just create the described getter
{
getter.ret = ret;
getter.params = params;
std::transform
(params.begin(), params.end(), getter.params.begin(),
[](efl::eolian::eo_parameter const& param)
{
return efl::eolian::eo_parameter
{ param.type + "*", param.name };
});
}
if (eina_list_count(keys_) > 0)
{
efl::eolian::parameters_container_type keys = _get_params(keys_, true);
keys.reserve(keys.size() + getter.params.size());
keys.insert(keys.end(), getter.params.begin(), getter.params.end());
getter.params = keys;
}
getter.comment = detail::eolian_property_getter_comment(property);
container.push_back(getter);
}
if (type == EOLIAN_PROP_SET || type == EOLIAN_PROPERTY)
{
const Eina_List *keys_ = eolian_property_keys_list_get(property);
const Eina_List *args_ = eolian_parameters_list_get(property);
Eina_List *params_ = eina_list_merge(eina_list_clone(keys_), eina_list_clone(args_));
efl::eolian::parameters_container_type params = _get_params(params_);
eina_list_free(params_);
efl::eolian::eo_function setter;
setter.type = efl::eolian::eo_function::regular_;
setter.name = name + "_set";
setter.impl = (prefix != "" ? prefix : cxx_classname) + "_" + setter.name;
setter.params = params;
setter.ret = safe_str(eolian_function_return_type_get
(property, EOLIAN_PROP_SET));
if (setter.ret == "") setter.ret = "void";
setter.comment = detail::eolian_property_setter_comment(property);
container.push_back(setter);
}
}
return container;
}
namespace detail {
void
convert_eolian_inheritances(efl::eolian::eo_class& cls, const char *classname)
{
const Eina_List *inheritances = eolian_class_inherits_list_get(classname);
const Eina_List *it;
void *curr;
if (eina_list_count(inheritances) == 0
|| eina_list_data_get(inheritances) == NULL)
{
cls.parent = "efl::eo::base";
return;
}
else
{
std::string parent =
static_cast<const char*>(eina_list_data_get(inheritances));
std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
// "eo_base" is the Eolian name for EO_BASE_CLASS.
cls.parent = (parent == "eo_base" || parent == "") ? "efl::eo::base" : parent;
}
inheritances = eina_list_next(inheritances);
EINA_LIST_FOREACH (inheritances, it, curr)
{
std::string extension = static_cast<const char*>(curr);
std::transform
(extension.begin(), extension.end(), extension.begin(), ::tolower);
cls.extensions.push_back(extension);
}
}
void
convert_eolian_implements(efl::eolian::eo_class& cls, const char *classname)
{
const Eina_List *it;
void *curr;
std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
const Eina_List *implements = eolian_class_implements_list_get(classname);
Eolian_Implement impl_desc;
void *impl_desc_;
EINA_LIST_FOREACH(eolian_class_implements_list_get(classname), it, impl_desc_)
{
Eolian_Implement impl_desc = static_cast<Eolian_Implement>(impl_desc_);
Eolian_Function_Type func_type;
const char *func_name;
const char *impl_class;
eolian_implement_information_get
(impl_desc, &impl_class, &func_name, &func_type);
#if 1 // XXX only due to a bug in Eolian we have to double-check
if(func_type == EOLIAN_UNRESOLVED &&
eolian_class_function_find_by_name(impl_class, func_name, EOLIAN_CTOR) != NULL)
func_type = EOLIAN_CTOR;
#endif
if (func_type == EOLIAN_CTOR)
{
efl::eolian::eo_constructor constructor;
Eolian_Function eolian_constructor = eolian_class_function_find_by_name
(impl_class, func_name, func_type);
assert(eolian_constructor != NULL);
std::string parent = safe_str(impl_class);
if(parent == "Eo_Base") parent = "eo";
else std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
constructor.name = parent + "_" + safe_str(func_name);
constructor.params = _get_params
(eolian_parameters_list_get(eolian_constructor));
constructor.comment = detail::eolian_constructor_comment
(eolian_constructor);
cls.constructors.push_back(constructor);
}
}
}
void
convert_eolian_constructors(efl::eolian::eo_class& cls, const char *classname)
{
const Eina_List *it;
void *curr;
std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
const Eina_List *constructors =
eolian_class_functions_list_get(classname, EOLIAN_CTOR);
EINA_LIST_FOREACH (constructors, it, curr)
{
Eolian_Function eolian_constructor = static_cast<Eolian_Function>(curr);
efl::eolian::eo_constructor constructor;
constructor.name = (prefix != "" ? prefix : cls.name) + "_" + safe_str
(eolian_function_name_get(eolian_constructor));
constructor.params = _get_params
(eolian_parameters_list_get(eolian_constructor));
constructor.comment = detail::eolian_constructor_comment
(eolian_constructor);
cls.constructors.push_back(constructor);
}
}
void
convert_eolian_functions(efl::eolian::eo_class& cls, const char *classname)
{
const Eina_List *it;
void *curr;
const Eina_List *eolian_functions =
eolian_class_functions_list_get(classname, EOLIAN_METHOD);
EINA_LIST_FOREACH (eolian_functions, it, curr)
{
efl::eolian::eo_function function;
Eolian_Function eolian_function = static_cast<Eolian_Function>(curr);
std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
// XXX Eolian only provides regular methods so far
function.type = efl::eolian::eo_function::regular_;
function.name = safe_str(eolian_function_name_get(eolian_function));
function.impl = ( prefix != "" ? prefix : cls.name ) + "_" + function.name;
function.ret = safe_str(eolian_function_return_type_get
(eolian_function, EOLIAN_METHOD));
if(function.ret == "") function.ret = "void";
function.params = _get_params(eolian_parameters_list_get(eolian_function));
function.comment = detail::eolian_function_comment(eolian_function);
cls.functions.push_back(function);
}
}
void
convert_eolian_properties(efl::eolian::eo_class& cls, const char *classname)
{
efl::eolian::functions_container_type properties = _get_properties(classname);
cls.functions.insert(cls.functions.end(), properties.begin(), properties.end());
}
} // namespace detail {
efl::eolian::eo_class
_cxx_new(const char *classname)
{
using namespace efl::eolian;
eo_class cls;
Eolian_Class_Type cls_type = ::eolian_class_type_get(classname);
if (cls_type == EOLIAN_CLASS_REGULAR) cls.type = eo_class::regular_;
else if (cls_type == EOLIAN_CLASS_ABSTRACT) cls.type = eo_class::regular_noninst_;
else if (cls_type == EOLIAN_CLASS_MIXIN) cls.type = eo_class::mixin_;
else if (cls_type == EOLIAN_CLASS_INTERFACE) cls.type = eo_class::interface_;
else { assert(false); }
std::string prefix(safe_str(eolian_class_eo_prefix_get(classname)));
cls.name = classname;
cls.eo_name = (prefix != "" ? prefix : cls.name) + "_CLASS";
cls.comment = detail::eolian_class_comment(classname);
std::transform(cls.name.begin(), cls.name.end(), cls.name.begin(), ::tolower);
std::transform(cls.eo_name.begin(), cls.eo_name.end(), cls.eo_name.begin(), ::toupper);
return cls;
}
efl::eolian::eo_class
c_to_cxx(const char *classname)
{
efl::eolian::eo_class cls(_cxx_new(classname));
detail::convert_eolian_inheritances(cls, classname);
detail::convert_eolian_implements(cls, classname);
detail::convert_eolian_constructors(cls, classname);
detail::convert_eolian_functions(cls, classname);
detail::convert_eolian_properties(cls, classname);
return cls;
}

View File

@ -0,0 +1,9 @@
#ifndef EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
#define EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
#include "eo_types.hh"
efl::eolian::eo_class c_to_cxx(const char *classname);
#endif // EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH

View File

@ -0,0 +1,62 @@
#ifndef EOLIAN_CXX_EOLIAN_HELPER_H
#define EOLIAN_CXX_EOLIAN_HELPER_H
#include <Eina.h>
#include <Eolian.h>
#include <assert.h>
#define EO_SUFFIX ".eo"
inline Eina_List*
_list_dir(const char *dir, const char *suffix, Eina_Bool recurse)
{
Eina_List *files = NULL;
Eina_Iterator *ls;
Eina_File_Direct_Info *info;
ls = eina_file_direct_ls(dir);
if(ls == NULL) return NULL;
EINA_ITERATOR_FOREACH (ls, info)
{
assert(info && info->path);
if (info->type == EINA_FILE_DIR && recurse)
{
files = eina_list_merge
(files, _list_dir(info->path, suffix, recurse));
}
else if (eina_str_has_suffix(&info->path[info->name_start], suffix))
{
files = eina_list_append(files, strdup(info->path));
}
}
eina_iterator_free(ls);
return eina_list_sort
(files, eina_list_count(files), EINA_COMPARE_CB(strcoll));
}
inline Eina_List*
eolian_read_from_fs(const char *path, Eina_Bool recurse)
{
if (eina_str_has_suffix(path, EO_SUFFIX))
{
if(!eolian_eo_file_parse(path))
{
/* XXX: fprintf? */
fprintf(stderr, "Couldn't load input file: %s\n", path);
return NULL;
}
}
else
{
if (!eolian_directory_scan(path))
{
/* XXX: fprintf? */
fprintf(stderr, "Error scanning directory: %s\n", path);
}
}
return eina_list_clone(eolian_class_names_list_get());
}
#endif /* EOLIAN_CXX_EOLIAN_HELPER_H */

View File

@ -0,0 +1,337 @@
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string>
#include <algorithm>
#include <stdexcept>
#include <iosfwd>
#include <type_traits>
#include <cassert>
extern "C"
{
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Eina.h>
#include <Eo.h>
#include <Eolian.h>
}
#include <Eina.hh>
#include <Eolian_Cxx.hh>
#include "eo_read.h"
#include "convert.hh"
#include "safe_strings.hh"
namespace {
// Program options.
struct options_type
{
std::vector<std::string> in_srcs;
std::string out_file;
std::string out_dir;
std::string classname;
std::string name_space;
bool recurse;
bool generate_all;
options_type()
: in_srcs()
, out_file("")
, out_dir("")
, classname("")
, name_space("")
, recurse(false)
, generate_all(false)
{}
};
efl::eina::log_domain domain("eolian_cxx");
}
static void
_opt_error(std::string message)
{
EINA_CXX_DOM_LOG_ERR(::domain) << message << std::endl;
exit(EXIT_FAILURE);
}
static void
_assert_not_dup(std::string option, std::string value)
{
if (value != "")
{
_opt_error("Option -" + option + " already set (" + value + ")");
}
}
// Try to guess classname from input filenames.
// Precondition: Input sources must be loaded into Eolian Database
// otherwise we can't infer the classname from the .eo files.
// Precondition: Input options must have opts.classname == "".
static std::string
_guess_classname_from_sources(::options_type& opts)
{
for (auto filename : opts.in_srcs)
{
if (const char *cls = eolian_class_find_by_file(filename.c_str()))
{
return cls;
}
}
return "";
}
efl::eolian::eo_generator_options
_resolve_includes(std::string const& classname, ::options_type const& opts)
{
efl::eolian::eo_generator_options gen_opts;
std::string cls_name = classname;
std::transform(cls_name.begin(), cls_name.end(), cls_name.begin(), ::tolower);
std::string eo_file = safe_str(eolian_class_file_get(classname.c_str()));
const size_t last = eo_file.rfind("/");
if (last != std::string::npos) eo_file.erase(0, last+1);
gen_opts.c_headers.push_back(eo_file + ".h");
void *cur = NULL;
const Eina_List *itr, *inheritances = eolian_class_inherits_list_get(classname.c_str());
EINA_LIST_FOREACH(inheritances, itr, cur)
{
const char *ext = static_cast<const char*>(cur);
std::string eo_parent_file = safe_str(eolian_class_file_get(ext));
if (!eo_parent_file.empty())
{
const size_t last = eo_parent_file.rfind("/");
if (last != std::string::npos) eo_parent_file.erase(0, last+1);
if (eo_parent_file != "eo_base.eo") // we have our own eo_base.hh
{
gen_opts.cxx_headers.push_back(eo_parent_file + ".hh");
}
}
else
{
EINA_CXX_DOM_LOG_WARN(::domain)
<< "Couldn't find source file for class '" << ext << "'";
}
}
return gen_opts;
}
static void
_generate(const std::string classname, ::options_type const& opts)
{
efl::eolian::eo_class cls = ::c_to_cxx(classname.c_str());
cls.name_space = opts.name_space;
efl::eolian::eo_class_validate(cls);
efl::eolian::eo_generator_options gen_opts = _resolve_includes(classname, opts);
std::string outname = (opts.out_file == "") ? (cls.name + ".eo.hh") : opts.out_file;
if (opts.out_dir != "")
{
outname = opts.out_dir + "/" + outname;
}
if(opts.out_file == "-")
{
efl::eolian::generate(std::cout, cls, gen_opts);
}
else
{
std::ofstream outfile;
outfile.open(outname);
assert(outfile.good());
efl::eolian::generate(outfile, cls, gen_opts);
outfile.close();
}
}
static void
_run(options_type const& opts)
{
if (opts.classname != "")
{
_generate(opts.classname.c_str(), opts);
}
else
{
efl::eina::range_ptr_list<const char* const>
classes(eolian_class_names_list_get());
for (auto cls : classes)
{
if (opts.classname == "" || opts.classname == cls)
{
_generate(cls, opts);
}
}
}
}
static void
_print_version()
{
std::cerr
<< "Eolian C++ Binding Generator (EFL "
<< PACKAGE_VERSION << ")" << std::endl;
}
static void
_validate_options(::options_type const& opts)
{
if (opts.in_srcs.size() == 0)
{
_opt_error("You must provide at least one input source (-I). "
"Either an .eo file or a directory of .eo files.");
}
else if (opts.out_file != "" && opts.generate_all)
{
_opt_error("Options -a and -o can't be used together.");
}
else if (!opts.generate_all && opts.classname == "")
{
_opt_error("Neither -a nor -c provided. "
"Don't know what to generate.");
}
}
static void
_resolve_classname(options_type& opts)
{
if (opts.classname == "")
{
std::string cls = _guess_classname_from_sources(opts);
opts.classname = cls;
}
if (opts.classname == "" && opts.out_file != "")
{
EINA_CXX_DOM_LOG_ERR(::domain)
<< "Unknown output class for " << opts.out_file
<< " : Missing '-c' option?";
std::abort();
}
}
static void
_load_classes(options_type const& opts)
{
for (auto src : opts.in_srcs)
{
if (eolian_read_from_fs(src.c_str(), opts.recurse) == NULL)
{
EINA_CXX_DOM_LOG_WARN(::domain)
<< "Couldn't load eolian file: " << src;
}
}
}
static void
_usage(const char *progname)
{
std::cerr
<< progname
<< " [options]" << std::endl
<< "Options:" << std::endl
<< " -a, --all Generate bindings for all Eo classes." << std::endl
<< " -c, --class <name> The Eo class name to generate code for." << std::endl
<< " -D, --out-dir <dir> Output directory where generated code will be written." << std::endl
<< " -I, --in <file/dir> The source containing the .eo descriptions." << std::endl
<< " -o, --out-file <file> The output file name. [default: <classname>.eo.hh]" << std::endl
<< " -n, --namespace <ns> Wrap generated code in a namespace. [Eg: efl::ecore::file]" << std::endl
<< " -r, --recurse Recurse input directories loading .eo files." << std::endl
<< " -v, --version Print the version." << std::endl
<< " -h, --help Print this help." << std::endl;
exit(EXIT_FAILURE);
}
static ::options_type
_read_options(int argc, char **argv)
{
::options_type opts;
const struct option long_options[] =
{
{ "in", required_argument, 0, 'I' },
{ "out-dir", required_argument, 0, 'D' },
{ "out-file", required_argument, 0, 'o' },
{ "class", required_argument, 0, 'c' },
{ "namespace", required_argument, 0, 'n' },
{ "all", no_argument, 0, 'a' },
{ "recurse", no_argument, 0, 'r' },
{ "version", no_argument, 0, 'v' },
{ "help", no_argument, 0, 'h' },
{ 0, 0, 0, 0 }
};
const char* options = "I:D:o:c:n:arvh";
int c, idx;
while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
{
if (c == 'I')
{
opts.in_srcs.push_back(optarg);
}
else if (c == 'D')
{
_assert_not_dup("D", opts.out_dir);
opts.out_dir = optarg;
}
else if (c == 'o')
{
_assert_not_dup("o", opts.out_file);
opts.out_file = optarg;
}
else if (c == 'c')
{
_assert_not_dup("c", opts.classname);
opts.classname = optarg;
}
else if (c == 'n')
{
_assert_not_dup("n", opts.name_space);
opts.name_space = optarg;
}
else if (c == 'a')
{
opts.generate_all = true;
}
else if (c == 'r')
{
opts.recurse = true;
}
else if (c == 'h')
{
_usage(argv[0]);
}
else if (c == 'v')
{
_print_version();
if (argc == 2) exit(EXIT_SUCCESS);
}
}
return opts;
}
int main(int argc, char **argv)
{
efl::eina::eina_init eina_init;
efl::eolian::eolian_init eolian_init;
#if DEBUG
domain.set_level(efl::eina::log_level::debug);
#endif
options_type opts = _read_options(argc, argv);
_load_classes(opts);
_resolve_classname(opts);
_validate_options(opts);
_run(opts);
return 0;
}

View File

@ -0,0 +1,28 @@
#ifndef EOLIAN_CXX_BIN_SAFE_STRINGS_HH
#define EOLIAN_CXX_BIN_SAFE_STRINGS_HH
#include <string>
extern "C"
{
#include <Eina.h>
}
/// @brief Safely convert an const char* to std::string.
inline std::string
safe_str(const char* str)
{
return (str != NULL) ? str : "";
}
/// @brief Safely convert an Eina_Stringshare to std::string.
inline std::string
safe_strshare(Eina_Stringshare* strsh)
{
std::string ret = strsh != NULL ? strsh : "";
eina_stringshare_del(strsh);
return ret;
}
#endif // EOLIAN_CXX_BIN_SAFE_STRINGS_HH

View File

@ -10,6 +10,10 @@
#include <memory>
#include <cstring>
#ifdef EFL_BETA_API_SUPPORT
#include <Ecore.eo.hh>
#endif
namespace efl { namespace ecore {
template <typename T>

View File

@ -0,0 +1,9 @@
#ifndef EFL_CXX_EO_HH
#define EFL_CXX_EO_HH
#include <eo_base.hh>
#include <eo_init.hh>
#include <eo_wref.hh>
#include <eo_inherit.hh>
#endif // EFL_CXX_EO_HH

View File

@ -0,0 +1,229 @@
///
/// @file eo_base.hh
///
#ifndef EFL_CXX_EO_BASE_HH
#define EFL_CXX_EO_BASE_HH
#include <cassert>
#include <stdexcept>
#include <cstddef>
#include <eina_optional.hh>
#include "eo_ops.hh"
namespace efl { namespace eo {
/// @addtogroup Efl_Cxx_API
/// @{
/// @brief A binding to the <em>EO Base Class</em>.
///
/// This class implements C++ wrappers to all the <em>EO Base</em>
/// operations.
///
struct base
{
/// @brief Class constructor.
///
/// @param eo The <em>EO Object</em>.
///
/// efl::eo::base constructors semantics are that of stealing the
/// <em>EO Object</em> lifecycle management. Its constructors do not
/// increment the <em>EO</em> reference counter but the destructors
/// do decrement.
///
explicit base(Eo* eo) : _eo_raw(eo)
{
assert(eo != 0);
}
/// @brief Class destructor.
///
~base()
{
detail::unref(_eo_raw);
}
/// @brief Assignment operator.
///
base& operator=(base const& other)
{
_eo_raw = detail::ref(other._eo_ptr());
return *this;
}
/// @brief Return a pointer to the <em>EO Object</em> stored in this
/// instance.
///
/// @return A pointer to the opaque <em>EO Object</em>.
///
Eo* _eo_ptr() const { return _eo_raw; }
/// @brief Get the reference count of this object.
///
/// @return The referencer count of this object.
///
int ref_get() const { return detail::ref_get(_eo_raw); }
/// @brief Set the parent of this object.
///
/// @param parent The new parent.
///
void parent_set(base parent)
{
detail::parent_set(_eo_raw, parent._eo_ptr());
}
/// @brief Get the parent of this object.
///
/// @return An @ref efl::eo::base instance that binds the parent
/// object. Returns NULL if there is no parent.
///
eina::optional<base> parent_get()
{
Eo *r = detail::parent_get(_eo_raw);
if(!r) return nullptr;
else
{
detail::ref(r); // XXX eo_parent_get does not call eo_ref so we may.
return base(r);
}
}
/// @brief Set generic data to object.
///
/// @param key The key associated with the data.
/// @param data The data to set.
/// @param free_func A pointer to the function that frees the
/// data. @c (::eo_key_data_free_func*)0 is valid.
///
void base_data_set(const char *key, const void *data, ::eo_key_data_free_func func)
{
detail::base_data_set(_eo_raw, key, data, func);
}
/// @brief Get generic data from object.
///
/// @param key The key associated with desired data.
/// @return A void pointer to the data.
///
void* base_data_get(const char *key)
{
return detail::base_data_get(_eo_raw, key);
}
/// @brief Delete generic data from object.
///
/// @param key The key associated with the data.
///
void base_data_del(const char *key)
{
detail::base_data_del(_eo_raw, key);
}
/// @brief Freeze any event directed to this object.
///
/// Prevents event callbacks from being called for this object.
///
void event_freeze()
{
detail::event_freeze(_eo_raw);
}
/// @brief Thaw the events of this object.
///
/// Let event callbacks be called for this object.
///
void event_thaw()
{
detail::event_thaw(_eo_raw);
}
/// @brief Get the event freeze count for this object.
///
/// @return The event freeze count for this object.
///
int event_freeze_get()
{
return detail::event_freeze_get(_eo_raw);
}
/// @brief Get debug information of this object.
///
/// @return The root node of the debug information tree.
///
Eo_Dbg_Info dbg_info_get()
{
Eo_Dbg_Info info;
detail::dbg_info_get(_eo_raw, &info);
return info;
}
protected:
Eo* _eo_raw; ///< The opaque <em>EO Object</em>.
};
/// @brief Downcast @p U to @p T.
///
/// @param T An <em>EO C++ Class</em>.
/// @param U An <em>EO C++ Class</em>.
///
/// @param object The target object.
/// @return This function returns a new instance of @p T if the
/// downcast is successful --- otherwise it raises a @c
/// std::runtime_error.
///
template <typename T, typename U>
T downcast(U object)
{
Eo *eo = object._eo_ptr();
if(detail::isa(eo, T::_eo_class()))
{
return T(detail::ref(eo));
}
else
{
throw std::runtime_error("Invalid cast");
}
}
///
/// @brief Type used to hold the parent passed to base Eo C++
/// constructors.
///
struct parent_type
{
Eo* _eo_raw;
};
///
/// @brief The expression type declaring the assignment operator used
/// in the parent argument of the base Eo C++ class.
///
struct parent_expr
{
parent_type operator=(efl::eo::base const& parent)
{
return { parent._eo_ptr() };
}
parent_type operator=(std::nullptr_t)
{
return { NULL };
}
};
///
/// @brief Placeholder for the parent argument.
///
parent_expr parent = {};
/// @}
} } // namespace efl { namespace eo {
#endif // EFL_CXX_EO_BASE_HH

View File

@ -0,0 +1,137 @@
///
/// @file eo_inherit.hh
///
#ifndef EFL_CXX_EO_INHERIT_HH
#define EFL_CXX_EO_INHERIT_HH
#include <tuple>
#include <cassert>
#include <eina_integer_sequence.hh>
#include "eo_ops.hh"
#include "eo_private.hh"
namespace efl { namespace eo {
namespace detail {
template <typename D, typename Args, typename... E, std::size_t... S>
Eo_Class const* create_class(eina::index_sequence<S...>);
template <typename Args, typename ... E>
void inherit_constructor(void* this_, Args args);
}
/// @addtogroup Efl_Cxx_API
/// @{
/// @brief Template-class that allows client code to inherit from
/// <em>EO C++ Classes</em> without the need to make explicit calls to
/// <em>EO</em> methods --- that would naturally be necessary to
/// register itself in the <em>EO Subsystem</em>.
///
/// @param D The derived class
/// @param O The parent class
/// @param E Class extensions (either mixins or interfaces)
///
/// The derived class @p D will inherit all EO operations and event
/// callbacks from the parent class @p P, as well as from the <c>Base
/// Class</c> (@ref efl::eo::base) since every EO C++ Class must
/// inherit from it.
///
/// efl::eo::inherit makes use of meta-template elements to build (in
/// compile-time) code capable of registering @p D as an <em>EO
/// Class</em> within <em>EO Subsystem</em>. Each class is registered
/// only once upon instantiation of an object of its type.
///
/// @note Function overriding is currently not supported.
///
template <typename D, typename... E>
struct inherit;
/// @}
/// @addtogroup Efl_Cxx_API
/// @{
template <typename D, typename... E>
struct inherit
: detail::operations<E>::template type<inherit<D, E...> > ...
, detail::conversion_operator<inherit<D, E...>, E>...
{
/// @typedef inherit_base
///
typedef inherit<D, E...> inherit_base;
/// @brief Class constructor.
///
/// @ref inherit has a "variadic" constructor implementation that
/// allows from zero to EFL_MAX_ARGS heterogeneous parameters.
///
template<typename... Args>
inherit(Args&& ... args)
{
typedef std::tuple<typename std::remove_reference<Args>::type...> tuple_type;
_eo_cls = detail::create_class<D, tuple_type, E...> (eina::make_index_sequence<sizeof...(E)>());
_eo_raw = eo_add_custom
(_eo_cls, NULL,
detail::inherit_constructor
<tuple_type, E...>
(static_cast<void*>(this), tuple_type(std::move(args)...)));
}
/// @brief Class destructor.
///
~inherit()
{
detail::unref(_eo_raw);
}
/// @brief Gets the <em>EO Object</em> corresponding to this <em>EO
/// C++ Object</em>.
///
/// @return A pointer to the <em>EO Object</em>.
///
Eo* _eo_ptr() const { return _eo_raw; }
/// @brief Gets the <em>EO Class</em> corresponding to this <em>EO
/// C++ Class</em>.
///
/// @return A pointer to the <em>EO Class</em>.
///
Eo_Class const* _eo_class() const { return _eo_cls; }
protected:
/// @brief Copy constructor.
///
inherit(inherit const& other)
: _eo_cls(other._eo_cls)
, _eo_raw(other._eo_raw)
{ detail::ref(_eo_raw); }
/// @brief Assignment Operator
///
inherit& operator=(inherit const& other)
{
_eo_cls = other._eo_cls;
_eo_raw = other._eo_raw;
detail::ref(_eo_raw);
return *this;
}
private:
Eo_Class const* _eo_cls; ///< The <em>EO Class</em>.
Eo* _eo_raw; ///< The <em>EO Object</em>.
};
/// @}
} } // namespace efl { namespace eo {
#include "eo_inherit_bindings.hh"
#endif // EFL_CXX_INHERIT_HH

View File

@ -0,0 +1,347 @@
#ifndef EFL_CXX_DETAIL_INHERIT_BINDINGS_HH
#define EFL_CXX_DETAIL_INHERIT_BINDINGS_HH
#include <typeinfo>
#include <eina_integer_sequence.hh>
namespace efl { namespace eo { namespace detail {
/// @addtogroup Efl_Cxx_Detail
/// @{
/// @internal
///
/// @brief Invokes the <em>EO C Constructor</em> that corresponds to the
/// binded <em>EO C++ Class</em>.
///
/// @param T The corresponding <em>EO C++ Class</em>
/// @param Args An heterogeneous list of constructor arguments
///
/// @param tag Used to instruct the compiler during compile-time which
/// of the overloads should be invoked.
/// @param eo A pointer to the <em>EO C Object</em> to be constructed.
/// @param cls Unused.
/// @param args An heterogenous vector containing the constructor
/// arguments, in the correct order.
///
/// To ensure full reciprocity of the C++ binding there must exist one
/// (and only one) implementation of @ref efl::eo::detail::call_constructor
/// for each available <em>EO C++ Class</em> --- the implementations
/// are differentiated by this unique specialization of
/// @ref efl::eo::detail::tag for the first argument of
/// @ref efl::eo::detail::call_constructor.
///
/// For example this is how the overload for @ref eo_simple is
/// written as follows:
///
/// @dontinclude eo_simple.hh
/// @skip call_constructor
/// @until }
///
/// As you can see @c ::simple_constructor is called with a single
/// argument in this case. Each EO Class has its own constructor
/// prototype -- which can have different argument types as well as
/// distinct number of arguments, etc. -- hence the need to specify a
/// choice for every known <em>EO C++ Class</em>.
///
/// @see efl::eo::detail::tag
///
template <typename T, typename Args>
void call_constructor(efl::eo::detail::tag<T> tag, Eo* eo, Eo_Class const* cls, Args args);
/// @internal
///
/// @brief Sums up the number of <em>EO Operations</em> of each class
/// passed as argument to the template.
///
/// @see efl::eo::detail::operation_description_class_size
///
template <typename... E>
struct operation_description_size;
template <typename E0, typename... E>
struct operation_description_size<E0, E...>
{
static const int value = operation_description_class_size<E0>::value +
operation_description_size<E...>::value;
};
template <>
struct operation_description_size<>
{
static const int value = 0;
};
template <typename T>
struct is_args_class : std::false_type
{
};
template <typename T, typename Tuple>
struct is_args_class<args_class<T, Tuple> >
: std::true_type
{
};
template <typename Tuple>
struct are_args_class;
template <>
struct are_args_class<std::tuple<> >
: std::true_type
{
};
template <typename T0, typename... T>
struct are_args_class<std::tuple<T0, T...> >
: std::integral_constant
<bool
, is_args_class<T0>::value
&& are_args_class<std::tuple<T...> >::value
>
{
};
template <typename T, typename Tuple>
struct has_args_class : std::false_type
{
typedef std::integral_constant<std::size_t, 0u> index;
};
template <typename T, typename Tuple, typename... Args>
struct has_args_class<T, std::tuple<detail::args_class<T, Tuple>, Args...> >
: std::true_type
{
typedef detail::args_class<T, Tuple> type;
typedef std::integral_constant<std::size_t, 0u> index;
};
template <typename T, typename T0, typename... Args>
struct has_args_class<T, std::tuple<T0, Args...> >
: has_args_class<T, std::tuple<Args...> >
{
typedef has_args_class<T, std::tuple<Args...> > base_type;
typedef std::integral_constant
<std::size_t, 1u + base_type::index::value> index;
};
/// @internal
///
/// @brief An auxiliary template-class used to select the correct
/// implementation of @ref efl::eo::call_constructor for @p T with
/// proper parameters and variadic size.
///
/// @param T An <em>EO C++ Class</em>.
///
template <typename T, std::size_t N>
struct call_constructor_aux
{
template <typename Args, typename P>
static void do_(Args const&, Eo* eo, Eo_Class const* cls
, P, typename std::enable_if<!P::value>::type* = 0)
{
call_constructor(tag<T>(), eo, cls, args_class<T, std::tuple<> >(std::tuple<>()));
}
template <typename Args, typename P>
static void do_(Args const& args, Eo* eo, Eo_Class const* cls
, P, typename std::enable_if<P::value>::type* = 0)
{
call_constructor(tag<T>(), eo, cls, std::get<P::index::value>(args));
}
/// @internal
///
/// @brief Invoke @def efl::eo::detail::call_constructor
/// implementation for the parent and each available extension.
///
/// @param args An heterogenous sequence of arguments.
/// @param eo The opaque <em>EO Object</em>.
/// @param cls The opaque <em>EO Class</em>.
///
template <typename Args>
static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
{
static_assert(std::tuple_size<Args>::value <= N, "");
static_assert(are_args_class<Args>::value, "");
do_(args, eo, cls, has_args_class<T, Args>());
return 0;
}
};
template <typename T>
struct call_constructor_aux<T, 1u>
{
template <typename Args>
static void do_(Args const& args, Eo* eo, Eo_Class const* cls
, std::true_type)
{
static_assert(std::tuple_size<Args>::value == 1, "");
static_assert(std::is_same
<typename std::tuple_element<0u, Args>::type::class_type
, T>::value, "");
call_constructor(tag<T>(), eo, cls, std::get<0u>(args));
}
template <typename Args>
static void do_(Args const& args, Eo* eo, Eo_Class const* cls
, std::false_type)
{
call_constructor(tag<T>(), eo, cls, args_class<T, Args>(args));
}
template <typename Args>
static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
{
do_(args, eo, cls, has_args_class<T, Args>());
return 0;
}
};
template <typename... Args>
void call_varargs(Args...)
{
}
/// @internal
///
/// @brief The procedure that actually is invoked when the constructor
/// of @c D is sought from the <em>EO Subsystem</em>.
///
/// @param obj The opaque <em>EO Object</em>.
/// @param self A pointer to @p obj's private data.
/// @param this_ A void pointer to the opaque <em>EO Class</em> ---
/// passed as <em>user data</em>.
/// @param args The arguments for the underlying constructor.
///
template <typename D, typename Args, typename... E>
void inherit_constructor_impl(Eo* obj, Inherit_Private_Data* self, void* this_, Args args)
{
self->this_ = this_;
Eo_Class const* cls = static_cast<inherit<D, E...>*>(this_)->_eo_class();
detail::call_varargs(detail::call_constructor_aux<E, sizeof...(E)>::do_(args, obj, cls) ...);
}
/// @internal
///
/// @brief Find the correct function for the <em>"constructor"</em>
/// operation and invoke it.
///
/// @param this_ The <em>user data</em> to be passed to the resolved function.
/// @param args An heterogeneous sequence of arguments.
///
template <typename Args, typename... E>
EAPI void inherit_constructor(void* this_, Args args)
{
typedef void (*func_t)(Eo *, void *, void*, Args);
Eo_Op_Call_Data call;
static Eo_Op op = EO_NOOP;
if ( op == EO_NOOP )
op = _eo_api_op_id_get
(reinterpret_cast<void*>
(static_cast<void(*)(void*, Args)>(&detail::inherit_constructor<Args, E...>)),
__FILE__, __LINE__);
if (!_eo_call_resolve("detail::inherit_constructor", op, &call, __FILE__, __LINE__))
{
assert(_eo_call_resolve("detail::inherit_constructor", op, &call, __FILE__, __LINE__));
return;
}
func_t func = (func_t) call.func;
EO_HOOK_CALL_PREPARE(eo_hook_call_pre);
func(call.obj, call.data, this_, args);
EO_HOOK_CALL_PREPARE(eo_hook_call_post);
}
template <typename T>
int initialize_operation_description(detail::tag<void>, void*);
template <std::size_t I, typename... E>
struct
operation_description_index
{
typedef std::tuple<E...> tuple_type;
static const std::size_t value =
detail::operation_description_size
< typename std::tuple_element
<I-1, tuple_type>::type >::value +
operation_description_index<I-1, E...>::value;
};
template <typename... E>
struct
operation_description_index<0u, E...>
{
static const std::size_t value = 0u;
};
/// @internal
///
/// @brief This function is responsible for declaring a new <em>EO C
/// Class</em> representing @p D within <em>EO Subsystem</em>.
///
/// @param D The derived class
/// @param P The parent class
/// @param En Class extensions (either mixins or interfaces)
/// @param Args An heterogeneous list of arguments to be passed to the
/// constructor of this class.
///
/// @see efl::eo::inherit::inherit
///
template <typename D, typename TupleArgs, typename... E, std::size_t ... S>
Eo_Class const* create_class(eina::index_sequence<S...>)
{
static const Eo_Class* my_class = NULL;
static Eo_Op_Description op_descs
[ detail::operation_description_size<E...>::value + 2 ];
op_descs[detail::operation_description_size<E...>::value].func =
reinterpret_cast<void*>
(
static_cast<void(*)(Eo*, Inherit_Private_Data*, void*, TupleArgs)>
(&detail::inherit_constructor_impl<D, TupleArgs, E...>)
);
op_descs[detail::operation_description_size<E...>::value].api_func =
reinterpret_cast<void*>
(
static_cast<void(*)(void*, TupleArgs)>
(&detail::inherit_constructor<TupleArgs, E...>)
);
op_descs[detail::operation_description_size<E...>::value].op = EO_NOOP;
op_descs[detail::operation_description_size<E...>::value].op_type = EO_OP_TYPE_REGULAR;
op_descs[detail::operation_description_size<E...>::value].doc = NULL;
op_descs[detail::operation_description_size<E...>::value+1].func = 0;
op_descs[detail::operation_description_size<E...>::value+1].api_func = 0;
op_descs[detail::operation_description_size<E...>::value+1].op = 0;
op_descs[detail::operation_description_size<E...>::value+1].op_type = EO_OP_TYPE_INVALID;
op_descs[detail::operation_description_size<E...>::value+1].doc = NULL;
typedef inherit<D, E...> inherit_type;
using namespace detail;
call_varargs(
initialize_operation_description<inherit_type>
(detail::tag<E>(),
&op_descs[operation_description_index<S, E...>::value]) ...
);
//locks
if(!my_class)
{
static Eo_Class_Description class_desc = {
EO_VERSION,
"Eo C++ Class",
EO_CLASS_TYPE_REGULAR,
EO_CLASS_DESCRIPTION_OPS(op_descs),
NULL,
sizeof(detail::Inherit_Private_Data),
NULL,
NULL
};
my_class = detail::do_eo_class_new<E...>(class_desc);
}
return my_class;
}
} } } // namespace efl { namespace eo { namespace detail {
#endif // EFL_CXX_DETAIL_INHERIT_BINDINGS_HH

View File

@ -0,0 +1,38 @@
///
/// @file eo_init.hh
///
#ifndef EFL_CXX_EO_INIT_HH
#define EFL_CXX_EO_INIT_HH
#include "eo_ops.hh"
namespace efl { namespace eo {
/// @addtogroup Efl_Cxx_API
/// @{
/// @brief A simple RAII implementation to initialize and terminate
/// the <em>EO Subsystem</em>.
///
struct eo_init
{
/// @brief Default constructor.
///
/// Invokes @c ::eo_init().
///
eo_init() { detail::init(); }
/// @brief Class destructor.
///
/// Invokes @c ::eo_shutdown().
///
~eo_init() { detail::shutdown(); }
};
/// @}
} }
#endif // EFL_CXX_EO_INIT_HH

View File

@ -0,0 +1,141 @@
#ifndef EFL_CXX_DETAIL_EO_OPS_HH
#define EFL_CXX_DETAIL_EO_OPS_HH
extern "C"
{
#include <Eo.h>
}
#define eo_macro_add_custom(klass, parent, ...) ({ \
eo_add_custom(klass, parent, __VA_ARGS__); \
})
namespace efl { namespace eo { namespace detail {
inline void
init()
{
::eo_init();
}
inline void
shutdown()
{
::eo_shutdown();
}
inline Eo*
ref(const Eo *obj)
{
return ::eo_ref(obj);
}
inline void
unref(const Eo *obj)
{
::eo_unref(obj);
}
inline int
ref_get(const Eo *obj)
{
return ::eo_ref_get(obj);
}
inline void
del(const Eo *obj)
{
::eo_del(obj);
}
inline Eina_Bool
isa(const Eo *obj, const Eo_Class *klass)
{
return eo_isa(obj, klass);
}
inline Eo*
add(const Eo_Class *klass, Eo *parent = NULL)
{
Eo *eo = eo_add(klass, parent);
return eo;
}
inline void
dbg_info_get(const Eo *obj, Eo_Dbg_Info *info)
{
eo_do(obj, eo_dbg_info_get(info));
}
inline void
base_data_set(const Eo *obj, const char *key, const void *data,
eo_key_data_free_func free_func = NULL)
{
eo_do(obj, eo_key_data_set(key, data, free_func));
}
inline void*
base_data_get(const Eo *obj, const char *key)
{
void *data;
eo_do(obj, data = eo_key_data_get(key));
return data;
}
inline void
base_data_del(const Eo *obj, const char *key)
{
eo_do(obj, eo_key_data_del(key));
}
inline void
parent_set(const Eo *obj, Eo *parent)
{
eo_do(obj, eo_parent_set(parent));
}
inline Eo*
parent_get(const Eo *obj)
{
Eo *parent;
eo_do(obj, parent = eo_parent_get());
return parent;
}
inline void
event_freeze(const Eo *obj)
{
eo_do(obj, eo_event_freeze());
}
inline void
event_thaw(const Eo *obj)
{
eo_do(obj, eo_event_thaw());
}
inline int
event_freeze_get(const Eo *obj)
{
int count = -1;
eo_do(obj, count = eo_event_freeze_get());
return count;
}
inline void
wref_add(const Eo *obj, Eo **wref)
{
eo_do(obj, eo_wref_add(wref));
}
inline void
wref_del(const Eo *obj, Eo **wref)
{
eo_do(obj, eo_wref_del(wref));
}
} } }
#endif // EFL_CXX_DETAIL_EO_OPS_HH

View File

@ -0,0 +1,160 @@
///
/// @file eo_private.hh
///
#ifndef EFL_CXX_EO_PRIVATE_HH
#define EFL_CXX_EO_PRIVATE_HH
#include "eo_ops.hh"
namespace efl { namespace eo { namespace detail {
/// @addtogroup Efl_Cxx_Detail
/// @{
/// @internal
///
/// @brief Provides a getter for an heterogeous sequence of arguments.
///
/// @param T An <em>EO C++ Class</em>
/// @param Seq An heterogenous sequence of arguments.
///
template <typename T, typename Tuple>
struct args_class
{
typedef T class_type;
/// @internal
///
/// @brief Class constructor.
///
/// @param tuple An heterogenous sequence of arguments.
///
args_class(Tuple tuple) : _tuple(tuple) {}
/// @internal
///
/// @brief Get the Nth element of the sequence.
///
/// @param N The index of the argument to be retrieved.
///
template <int N>
typename std::remove_reference
<
typename std::tuple_element<N, Tuple>::type
>::type get() const
{
return std::get<N>(_tuple);
}
///
/// TODO document.
///
constexpr std::size_t size() const
{
return std::tuple_size<Tuple>::value;
}
Tuple _tuple; ///< The sequence of arguments.
};
/// @internal
///
/// @brief A simple generic tag to help keeping track of a type.
///
/// @details
/// Used to mimic what would be a "template specialization" of a
/// function through the overload of an argument of type @ref
/// efl::eo::detail::tag --- because @c C++0x does not implement
/// template specialization of functions.
///
template <typename T> struct tag {};
/// @internal
///
/// @brief Invokes the different implementations of @ref
/// efl::eo::detail::eo_class_new for the parent and all extensions.
///
/// @see efl::eo::detail::eo_class_new
///
template <typename ... E>
Eo_Class const* do_eo_class_new(Eo_Class_Description& class_desc)
{
return eo_class_new(&class_desc, get_eo_class(tag<E>())..., (void*)NULL);
}
template <typename T> struct operation_description_class_size;
/// @internal
///
/// @brief Provides the operator to convert @p T to @p D.
///
/// @param D The target (derived) class
/// @param T An <em>EO C++ Class</em>
///
template <typename D, typename T>
struct conversion_operator
{
operator T() const
{
detail::ref(static_cast<D const*>(this)->_eo_ptr());
return T(static_cast<D const*>(this)->_eo_ptr());
}
};
/// @}
} // namespace detail {
template <typename T, typename... A>
detail::args_class<T, std::tuple< A... > >
args(A... arg)
{
return detail::args_class<T, std::tuple<A...> >(std::tuple<A...>(arg...));
}
namespace detail {
/// @addtogroup Efl_Cxx_Detail
/// @{
/// @internal
///
/// @brief Provides all operations of type @p T.
///
/// @param T An <em>EO C++ Class</em>
///
/// There must be an unique specialization of this class for each
/// declared <em>EO C++ Class</em>.
///
template <typename T> struct operations;
/// @internal
///
/// @brief Provides the operations of an extension as well as its
/// conversion operator.
///
/// @param T The <em>EO C++ Extension</em>
///
/// There must be an unique specialization of @ref
/// efl::eo::detail::extension_inheritance for each known <em>EO C++
/// Extension</em> -- i.e., @em Interfaces and @em Mixins.
///
template <typename T>
struct extension_inheritance {};
/// @internal
///
/// @brief efl::eo::inherit's private data.
///
struct Inherit_Private_Data
{
void* this_;
};
/// @}
} } } // namespace efl { namespace eo { namespace detail {
#endif

View File

@ -0,0 +1,126 @@
///
/// @file eo_wref.hh
///
#ifndef EFL_CXX_WREF_HH
#define EFL_CXX_WREF_HH
#include <eina_optional.hh>
#include "eo_ops.hh"
namespace efl { namespace eo {
/// @addtogroup Efl_Cxx_API
/// @{
/// @brief Weak references to an <em>EO Object</em>.
///
template<typename T>
struct wref {
/// @brief Class constructor.
///
/// @param obj The <em>EO Object</em> to be referenced.
///
/// Create a weak reference to @p obj.
///
explicit wref(Eo* obj) : _eo_wref(obj)
{
_add();
}
/// @brief Class constructor.
///
/// @param obj The <em>EO C++ Object</em> to be referenced.
///
/// Create a weak reference to @p obj.
///
wref(T obj) : _eo_wref(obj._eo_ptr())
{
_add();
}
/// @brief Class destructor.
///
~wref()
{
if(eina::optional<T> p = lock())
_del();
}
/// @brief Try to acquire a strong reference to the underlying
/// <em>EO Object</em>.
///
/// This function checks whether the weak reference still points to
/// a valid <em>EO Object</em>. If the reference is still valid it
/// increments the reference counter of the object and returns a
/// pointer to it.
///
/// @return If the lock was successfully acquired it returns a
/// strong reference to the <em>EO Object</em>. Otherwise it returns
/// an empty eina::optional.
///
eina::optional<T> lock()
{
if(_eo_wref) // XXX eo_ref() should work on multi-threaded environments
{
detail::ref(_eo_wref);
}
else
{
return nullptr;
}
return T(_eo_wref);
}
/// @brief Copy constructor.
///
wref(wref const& other)
: _eo_wref(other._eo_wref)
{
if(eina::optional<T> p = lock())
{
_add();
}
else
{
_eo_wref = 0;
}
}
/// @brief Assignment operator.
///
wref& operator=(wref const& other)
{
_eo_wref = other._eo_wref;
if(eina::optional<T> p = lock())
{
_add();
}
else
{
_eo_wref = 0;
}
}
private:
void _add()
{
detail::wref_add(_eo_wref, &_eo_wref);
}
void _del()
{
detail::wref_del(_eo_wref, &_eo_wref);
}
Eo* _eo_wref; ///< The weak reference.
};
/// @}
} } // namespace efl { namespace eo {
#endif // EFL_CXX_WREF_HH

3
src/examples/eolian_cxx/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/eolian_cxx_simple_01
/eolian_cxx_inherit_01
/eolian_cxx_evas_images

View File

@ -0,0 +1,114 @@
AUTOMAKE_OPTIONS = subdir-objects
MAINTAINERCLEANFILES = Makefile.in
AM_CXXFLAGS = \
-I. \
-I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/eina \
-I$(top_builddir)/src/lib/eina \
-I$(top_srcdir)/src/lib/eo \
-I$(top_builddir)/src/lib/eo \
-I$(top_srcdir)/src/bindings/eo_cxx \
-I$(top_builddir)/src/bindings/eo_cxx \
-I$(top_srcdir)/src/bindings/eina_cxx \
-I$(top_builddir)/src/bindings/eina_cxx \
-I$(top_srcdir)/src/lib/evas/ \
-I$(top_builddir)/src/lib/evas/ \
-I$(top_srcdir)/src/lib/evas/common \
-I$(top_builddir)/src/lib/evas/common \
-I$(top_srcdir)/src/lib/evas/canvas \
-I$(top_builddir)/src/lib/evas/canvas \
-I$(top_srcdir)/src/lib/ecore \
-I$(top_builddir)/src/lib/ecore \
-I$(top_srcdir)/src/lib/ecore_evas \
-I$(top_builddir)/src/lib/ecore_evas
AM_CFLAGS = $(AM_CXXFLAGS)
AM_LDFLAGS = \
-L$(top_builddir)/src/lib/efl \
-L$(top_builddir)/src/lib/eina \
-L$(top_builddir)/src/lib/eo \
-L$(top_builddir)/src/lib/evas \
-L$(top_builddir)/src/lib/ecore \
-L$(top_builddir)/src/lib/ecore_evas \
-leina -levas -leo -lecore -lecore_evas
LDADD = \
$(top_builddir)/src/lib/eo/libeo.la \
$(top_builddir)/src/lib/eina/libeina.la \
$(top_builddir)/src/lib/evas/libevas.la \
$(top_builddir)/src/lib/ecore_evas/libecore_evas.la
GENERATED = \
colourable.eo.c \
colourable.eo.h \
colourable.eo.hh \
colourablesquare.eo.c \
colourablesquare.eo.h \
colourablesquare.eo.hh
EOS = \
colourable.eo \
colourablesquare.eo
SRCS = \
eolian_cxx_simple_01.cc \
eolian_cxx_inherit_01.cc
EXTRA_PROGRAMS = \
eolian_cxx_simple_01 \
eolian_cxx_inherit_01
DATA_FILES = Makefile.examples
CLEANFILES =
eolian_cxx_simple_01_SOURCES = \
eolian_cxx_simple_01.cc \
colourable.c \
colourablesquare.c
eolian_cxx_inherit_01_SOURCES = \
eolian_cxx_inherit_01.cc \
colourable.c \
colourablesquare.c
EOLIAN_GEN = $(top_builddir)/src/bin/eolian/eolian_gen${EXEEXT}
EOLIAN_CXX = $(top_builddir)/src/bin/eolian_cxx/eolian_cxx${EXEEXT}
EOLIAN_FLAGS = \
-I. \
-I$(top_builddir)/src/lib/eo \
-I$(top_builddir)/src/lib/evas/canvas \
-I$(top_builddir)/src/lib/edje \
-I$(top_builddir)/src/lib/ecore_audio
SUFFIXES = .eo .eo.c .eo.h .eo.hh
%.eo.hh: %.eo $(EOLIAN_CXX)
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I./$< -o $@
%.eo.c: %.eo $(EOLIAN_GEN)
$(AM_V_EOL)$(EOLIAN_GEN) --eo --legacy $(EOLIAN_FLAGS) --gc -o $@ $<
%.eo.h: %.eo $(EOLIAN_GEN)
$(AM_V_EOL)$(EOLIAN_GEN) --eo $(EOLIAN_FLAGS) --gh -o $@ $<
examples: $(EOS) $(GENERATED) $(EXTRA_PROGRAMS)
clean-local:
rm -f $(EXTRA_PROGRAMS) $(GENERATED)
install-examples:
mkdir -p $(datadir)/eolian_cxx/examples
$(install_sh_DATA) -c $(SRCS) $(DATA_FILES) $(datadir)/eolian_cxx/examples
uninstall-local:
for f in $(SRCS) $(DATA_FILES); do \
rm -f $(datadir)/eolian_cxx/examples/$$f ; \
done
if ALWAYS_BUILD_EXAMPLES
noinst_PROGRAMS = $(EXTRA_PROGRAMS)
endif

View File

@ -0,0 +1,165 @@
#include <stdio.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "Eo.h"
#include "Eina.h"
#include "colourable.eo.h"
#define MY_CLASS COLOURABLE_CLASS
static int _colourable_impl_logdomain;
#ifdef DBG
#undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_colourable_impl_logdomain, __VA_ARGS__)
#ifdef INFO
#undef INFO
#endif
#define INFO(...) EINA_LOG_DOM_INFO(_colourable_impl_logdomain, __VA_ARGS__)
#ifdef ERR
#undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_colourable_impl_logdomain, __VA_ARGS__)
struct _Colourable_Data
{
int r;
int g;
int b;
};
typedef struct _Colourable_Data Colourable_Data;
#define COLOURABLE_DATA_GET(o, wd) \
Colourable_Data *wd = eo_data_scope_get(o, MY_CLASS)
void
_colourable_constructor(Eo *obj, Colourable_Data *self)
{
if(!_colourable_impl_logdomain)
{
_colourable_impl_logdomain
= eina_log_domain_register("colourable", EINA_COLOR_BLUE);
}
DBG("_colourable_constructor(%p, %p)\n", obj, MY_CLASS);
eo_do_super(obj, MY_CLASS, eo_constructor());
}
void
_colourable_destructor(Eo *obj, Colourable_Data *self)
{
if(_colourable_impl_logdomain)
{
eina_log_domain_unregister(_colourable_impl_logdomain);
_colourable_impl_logdomain = 0;
}
DBG("_colourable_destructor()\n");
eo_do_super(obj, MY_CLASS, eo_destructor());
}
void
_colourable_rgb_composite_constructor(Eo *obj, Colourable_Data *self, int r, int g, int b)
{
if(!_colourable_impl_logdomain)
{
_colourable_impl_logdomain
= eina_log_domain_register("colourable", EINA_COLOR_BLUE);
}
self->r = r;
self->g = g;
self->b = b;
DBG("_colourable_rgb_composite_constructor(0x%2.x, %0x2.x, %0x2.x)\n",
(unsigned int)self->r,
(unsigned int)self->g,
(unsigned int)self->b);
eo_do_super(obj, MY_CLASS, eo_constructor());
}
void
_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
{
if(!_colourable_impl_logdomain)
{
_colourable_impl_logdomain
= eina_log_domain_register("colourable", EINA_COLOR_BLUE);
}
self->r = (rgb & 0x00ff0000) >> 16;
self->g = (rgb & 0x0000ff00) >> 8;
self->b = rgb & 0x000000ff;
DBG("_colourable_rgb_24bits_constructor(0x%.6x)\n", (int)rgb);
eo_do_super(obj, MY_CLASS, eo_constructor());
}
void
_colourable_print_colour(Eo *obj, Colourable_Data *self)
{
DBG("_colourable_print_colour() ==> 0x%2.x 0x%2.x 0x%2.x\n", self->r, self->g, self->b);
}
int
_colourable_colour_mask(Eo *obj, Colourable_Data *self, int mask)
{
int masked_rgb =
(((self->r << 16)& 0x00ff0000) |
((self->g << 8) & 0x0000ff00) |
(self->b & 0x000000ff)) & mask;
DBG("_colourable_colour_mask() ==> 0x%2.x\n", (unsigned int)masked_rgb);
return masked_rgb;
}
void
_colourable_composite_colour_get(Eo *obj, Colourable_Data *self, int* r, int* g, int* b)
{
*r = self->r;
*g = self->g;
*b = self->b;
DBG("_colourable_composite_colour_get() ==> 0x%2.x 0x%2.x 0x%2.x\n", *r, *g, *b);
return;
}
void
_colourable_composite_colour_set(Eo *obj, Colourable_Data *self, int r, int g, int b)
{
self->r = r;
self->g = g;
self->b = b;
DBG("_colourable_composite_colour_set(0x%2.x, 0x%2.x, 0x%2.x)\n",
(int)self->r, (int)self->g, (int)self->b);
return;
}
int
_colourable_colour_get(Eo *obj, Colourable_Data *self)
{
int rgb =
((self->r << 16)& 0x00ff0000) |
((self->g << 8) & 0x0000ff00) |
(self->b & 0x000000ff);
DBG("_colourable_colour_get() ==> 0x%.6x\n", (unsigned int)rgb);
return rgb;
}
void
_colourable_colour_set(Eo *obj, Colourable_Data *self, int rgb)
{
self->r = (rgb & 0x00ff0000) >> 16;
self->g = (rgb & 0x0000ff00) >> 8;
self->b = rgb & 0x000000ff;
DBG("_colourable_colour_set(0x%.6x)\n", (unsigned int)rgb);
return;
}
static void
_user_colourable_class_constructor(Eo_Class *klass)
{
DBG("_colourable_class_constructor()\n");
}
#include "colourable.eo.c"

View File

@ -0,0 +1,63 @@
class Colourable (Eo_Base)
{
/*@ Colourable class. */
legacy_prefix: legacy;
constructors {
constructor {
/*@ Default constructor. */
}
rgb_composite_constructor {
/*@ Composite RGB Constructor. */
params {
@in int r; /*@ The red component. */
@in int g; /*@ The green component. */
@in int b; /*@ The blue component. */
};
};
rgb_24bits_constructor {
/*@ RGB Constructor. */
params {
@in int rgb; /*@ 24-bit RGB Component. */
};
};
};
methods {
print_colour { /*@ Print the RGB colour. */ };
colour_mask {
/*@ The masked RGB value. */
return int;
params {
@in int mask; /*@ The colour mask to be applied to current RGB value. */
};
};
};
properties {
colour {
set {
/*@ Sets a 24-bit RGB colour. */
};
get {
/*@ Gets the 24-bit RGB colour. */
};
values {
int rgb; /*@ The RGB colour value. */
};
};
composite_colour {
set {
/*@ Sets a composite RGB colour. */
};
get {
/*@ Gets the composite RGB colour. */
};
values {
int r; /*@ The red component. */
int g; /*@ The green component. */
int b; /*@ The blue component. */
};
};
};
events {
colour_changed(int);
};
};

View File

@ -0,0 +1,91 @@
#include <stdio.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "Eo.h"
#include "colourable.eo.h"
#include "colourablesquare.eo.h"
#define MY_CLASS COLOURABLESQUARE_CLASS
static int _colourablesquare_impl_logdomain;
#ifdef DBG
#undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_colourablesquare_impl_logdomain, __VA_ARGS__)
#ifdef INFO
#undef INFO
#endif
#define INFO(...) EINA_LOG_DOM_INFO(_colourablesquare_impl_logdomain, __VA_ARGS__)
#ifdef ERR
#undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_colourablesquare_impl_logdomain, __VA_ARGS__)
struct _ColourableSquare_Data
{
int size;
};
typedef struct _ColourableSquare_Data ColourableSquare_Data;
#define COLOURABLESQUARE_DATA_GET(o, wd) \
ColourableSquare_Data *wd = eo_data_scope_get(o, MY_CLASS)
static void
_colourablesquare_size_constructor(Eo *obj, ColourableSquare_Data *self, int size)
{
if(!_colourablesquare_impl_logdomain)
{
_colourablesquare_impl_logdomain
= eina_log_domain_register
("colourablesquare", EINA_COLOR_LIGHTBLUE);
}
self->size = size;
DBG("_colourablesquare_constructor(%d)\n", size);
eo_do_super(obj, MY_CLASS, eo_constructor());
}
static void
_colourablesquare_destructor(Eo *obj, ColourableSquare_Data *self)
{
eo_do_super(obj, MY_CLASS, eo_destructor());
if(_colourablesquare_impl_logdomain)
{
eina_log_domain_unregister(_colourablesquare_impl_logdomain);
_colourablesquare_impl_logdomain = 0;
}
}
static int
_colourablesquare_size_get(Eo *obj, ColourableSquare_Data *self)
{
DBG("_colourablesquare_size_get() => %d\n", self->size);
return self->size;
}
static void
_colourablesquare_size_print(Eo *obj, ColourableSquare_Data *self)
{
DBG("_colourablesquare_size_print() ==> %d\n", self->size);
}
static void
_colourablesquare_size_set(Eo *obj, ColourableSquare_Data *self, int size)
{
DBG("_colourablesquare_size_set(%d)\n", size);
}
static void
_user_colourablesquare_class_constructor(Eo_Class *klass)
{
DBG("_colourablesquare_class_constructor()\n");
}
#include "colourablesquare.eo.c"

View File

@ -0,0 +1,23 @@
class ColourableSquare (Colourable)
{
constructors {
size_constructor { params { @in int size; } }
};
legacy_prefix: legacy;
properties {
size {
values {
int size;
};
set {
/*@ Sets size. */
};
get {
/*@ Gets size. */
};
};
};
methods {
size_print { /*@ Show the square. */ };
};
};

View File

@ -0,0 +1,69 @@
#include <iostream>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "colourable.eo.hh"
#include "colourablesquare.eo.hh"
#include <eo_inherit.hh>
using namespace efl;
struct ColourableCircle
: efl::eo::inherit<ColourableCircle, ::colourable>
{
ColourableCircle(int r, int g, int b)
: inherit_base(r, g, b)
{}
ColourableCircle(int rgb)
: inherit_base(efl::eo::args<::colourable>(rgb))
{}
int colour_get()
{
int rgb = 0;
eo_do_super(_eo_ptr(), _eo_class(), rgb = ::colourable_colour_get());
std::cout << "ColourableCircle::colour_get(" << this << ") ==> "
<< std::hex << rgb << std::endl;
return rgb;
}
};
struct ColourableFoo
: efl::eo::inherit<ColourableFoo,
::colourable,
::colourablesquare>
{
ColourableFoo(int size, int rgb)
: inherit_base(efl::eo::args<::colourable>(size)
, efl::eo::args<::colourablesquare>(rgb))
{}
};
int
main()
{
efl::eo::eo_init init;
eina_log_domain_level_set("colourable", EINA_LOG_LEVEL_DBG);
ColourableCircle obj1(0xc0, 0xff, 0xee);
ColourableCircle obj2(0xc0ffee);
int r, g, b;
obj2.composite_colour_get(&r, &g, &b);
assert(r == 0xc0);
assert(g == 0xff);
assert(b == 0xee);
assert(obj1.colour_get() == obj2.colour_get());
// ColourableFoo obj3(10, 0xc0ffee);
return 0;
}

View File

@ -0,0 +1,35 @@
// EINA_LOG_LEVELS=colourable:4,colourablesquare:4 ./eolian_cxx_simple_01
#include <iostream>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "colourable.eo.hh"
#include "colourablesquare.eo.hh"
int
main()
{
efl::eo::eo_init init;
eina_log_domain_level_set("colourable", EINA_LOG_LEVEL_DBG);
eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG);
int r, g, b;
::colourable obj1(0x123456);
obj1.colour_set(0xc0ffee);
obj1.composite_colour_get(&r, &g, &b);
::colourablesquare obj2(0x123456);
obj2.composite_colour_set(r, g, b);
obj2.size_set(11);
assert(obj1.colour_get() == obj2.colour_get());
efl::eo::wref<::colourable> ref = obj1;
efl::eina::optional<::colourable> obj3 = ref.lock();
assert(obj3);
obj3->colour_set(0x00);
return 0;
}

View File

@ -204,6 +204,21 @@ evas_aspect_hints_SOURCES = evas-aspect-hints.c
evas_aspect_hints_CPPFLAGS = $(EDJE_COMMON_CPPFLAGS)
evas_aspect_hints_LDADD = $(EDJE_COMMON_LDADD)
EXTRA_PROGRAMS += evas_cxx_rectangle
evas_cxx_rectangle_SOURCES = \
evas_cxx_rectangle.cc \
$(top_builddir)/src/lib/evas/canvas/evas_common_interface.eo.hh \
$(top_builddir)/src/lib/evas/canvas/evas.eo.hh \
$(top_builddir)/src/lib/evas/canvas/evas_object.eo.hh \
$(top_builddir)/src/lib/evas/canvas/evas_image.eo.hh
evas_cxx_rectangle_LDADD = $(ECORE_EVAS_COMMON_LDADD)
evas_cxx_rectangle_CPPFLAGS = \
-I$(top_srcdir)/src/bindings/eina_cxx \
-I$(top_builddir)/src/bindings/eina_cxx \
-I$(top_srcdir)/src/bindings/eo_cxx \
-I$(top_builddir)/src/bindings/eo_cxx \
$(ECORE_EVAS_COMMON_CPPFLAGS)
EDJS = $(EDCS:%.edc=%.edj)
SRCS = \

View File

@ -0,0 +1,56 @@
#include <iostream>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Evas.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Eina.hh>
#include <Eo.hh>
#include "canvas/evas.eo.hh"
#include "canvas/evas_image.eo.hh"
#include "canvas/evas_rectangle.eo.hh"
#define WIDTH (320)
#define HEIGHT (240)
int main()
{
efl::eina::eina_init eina_init;
efl::eo::eo_init init;
if (!::ecore_evas_init()) return EXIT_FAILURE;
if (!::evas_init()) return EXIT_FAILURE;
Ecore_Evas *ee = ::ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
if (!ee)
{
fprintf(stderr,
"you got to have at least one evas engine built and linked"
" up to ecore-evas for this example to run properly.\n");
::ecore_evas_free(ee);
return -1;
}
ecore_evas_show(ee);
{
::evas canvas(::eo_ref(::ecore_evas_get(ee)));
::evas_rectangle rect(efl::eo::parent = canvas);
rect.color_set(255, 0, 0, 255);
rect.position_set(10, 10);
rect.size_set(100, 100);
rect.visibility_set(true);
canvas.render();
}
::ecore_main_loop_begin();
::ecore_evas_free(ee);
::ecore_evas_shutdown();
return 0;
}

5
src/lib/.gitignore vendored
View File

@ -1,3 +1,8 @@
/ecore_x/ecore_x_version.h
/efl/Efl_Config.h
/eina/eina_config.h
/ecore_audio/Ecore_Audio.hh
/ecore/Ecore.eo.hh
/evas/Evas.hh
/edje/Edje.hh
/edje/Edje.eo.hh

View File

@ -0,0 +1,37 @@
#ifndef EOLIAN_CXX_LIB_HH
#define EOLIAN_CXX_LIB_HH
extern "C"
{
#include <Eolian.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
}
namespace efl { namespace eolian {
struct eolian_init
{
eolian_init()
{
::eolian_init();
}
~eolian_init()
{
::eolian_shutdown();
}
};
} }
#ifdef EFL_BETA_API_SUPPORT
#include "eo_types.hh"
#include "eo_validate.hh"
#include "eo_generate.hh"
#endif
#endif // EOLIAN_CXX_LIB_HH

View File

@ -0,0 +1,20 @@
#ifndef EOLIAN_CXX_EO_GENERATE_HH
#define EOLIAN_CXX_EO_GENERATE_HH
#include "eo_types.hh"
#include <iosfwd>
#include "grammar/eo_header_generator.hh"
namespace efl { namespace eolian {
inline void
generate(std::ostream& out, eo_class cls, eo_generator_options const& opts)
{
grammar::eo_header_generator(out, cls, opts);
}
} }
#endif // EOLIAN_CXX_EO_GENERATE_HH

View File

@ -0,0 +1,89 @@
#ifndef EOLIAN_CXX_EO_TYPES_HH
#define EOLIAN_CXX_EO_TYPES_HH
#include <string>
#include <vector>
namespace efl { namespace eolian {
struct eo_constructor;
struct eo_parameter;
struct eo_function;
struct eo_event;
typedef std::vector<std::string> extensions_container_type;
typedef std::vector<eo_constructor> constructors_container_type;
typedef std::vector<eo_function> functions_container_type;
typedef std::vector<eo_parameter> parameters_container_type;
typedef std::vector<eo_event> events_container_type;
struct eo_generator_options
{
std::vector<std::string> cxx_headers;
std::vector<std::string> c_headers;
};
struct eo_class
{
enum eo_class_type
{
regular_, regular_noninst_, interface_, mixin_
};
eo_class_type type;
std::string name;
std::string eo_name;
std::string parent;
extensions_container_type extensions;
constructors_container_type constructors;
functions_container_type functions;
events_container_type events;
std::string comment;
std::string name_space;
};
struct eo_parameter
{
std::string type;
std::string name;
};
struct eo_constructor
{
std::string name;
parameters_container_type params;
std::string comment;
};
struct eo_function
{
enum eo_function_type
{
regular_, class_
};
eo_function_type type;
std::string name;
std::string impl;
std::string ret;
parameters_container_type params;
std::string comment;
};
inline bool
function_is_void(eo_function const& func)
{
return func.ret == "void" || func.ret == "";
}
struct eo_event
{
std::string name;
parameters_container_type params;
bool is_hot;
std::string comment;
};
} }
#endif // EFL_EOLIAN_CXX_EO_TYPES_HH

View File

@ -0,0 +1,91 @@
#ifndef EOLIAN_CXX_EO_CLASS_VALIDATE_HH
#define EOLIAN_CXX_EO_CLASS_VALIDATE_HH
#include <string>
#include <cassert>
#ifdef DEBUG
#include <iostream>
#endif
#include "eo_types.hh"
namespace efl { namespace eolian {
inline bool
_isvalid(const std::string& name)
{
return name.size() > 0 and isalpha(name[0]);
}
inline void
_dbg(const std::string& msg)
{
#ifdef DEBUG
std::cerr << "eo_validate() - " << msg << std::endl;
#endif
}
inline void
eo_class_validate(const eo_class& cls)
{
_dbg("class name... " + cls.name);
assert(_isvalid(cls.name));
_dbg("class type... " + cls.type);
assert(cls.type != eo_class::regular_ ||
cls.type != eo_class::regular_noninst_ ||
cls.type != eo_class::interface_ ||
cls.type != eo_class::mixin_);
{
constructors_container_type::const_iterator it,
first = cls.constructors.begin(),
last = cls.constructors.end();
for (it = first; it != last; ++it)
{
parameters_container_type::const_iterator
param = (*it).params.begin(),
last_param = (*it).params.end();
_dbg("constructor... " + (*it).name);
assert(_isvalid((*it).name));
for (; param != last_param; ++param)
{
_dbg("constructor parameter... " + (*param).name);
assert(_isvalid((*param).name));
_dbg("constructor parameter type... " + (*param).type);
assert(_isvalid((*param).type));
}
}
}
{
functions_container_type::const_iterator it,
first = cls.functions.begin(),
last = cls.functions.end();
for (it = first; it != last; ++it)
{
_dbg("function... " + (*it).name);
assert(_isvalid((*it).name));
_dbg("function api... " + (*it).impl);
assert(_isvalid((*it).impl));
_dbg("function return... " + (*it).ret);
assert(_isvalid((*it).ret));
parameters_container_type::const_iterator
param = (*it).params.begin(),
last_param = (*it).params.end();
for (; param != last_param; ++param)
{
_dbg("function parameter... " + (*param).name);
assert(_isvalid((*param).name));
_dbg("function parameter type... " + (*param).type);
assert(_isvalid((*param).type));
}
}
}
}
} } // namespace efl { namespace eolian {
#endif // EOLIAN_CXX_EO_CLASS_VALIDATE_HH

View File

@ -0,0 +1,42 @@
#ifndef EOLIAN_CXX_STD_COMMENT_HH
#define EOLIAN_CXX_STD_COMMENT_HH
#include <iosfwd>
#include <ostream>
#include <sstream>
#include "tab.hh"
namespace efl { namespace eolian { namespace grammar {
using std::endl;
const std::string comment_prefix("///");
struct comment
{
std::string _doc;
int _tab;
comment(std::string const& doc, int tab = 0)
: _doc(doc), _tab(tab)
{}
};
inline std::ostream&
operator<<(std::ostream& out, comment const& x)
{
std::istringstream ss(x._doc);
std::string line;
while(std::getline(ss, line))
{
out << tab(x._tab) << comment_prefix
<< (line.size() ? (" " + line) : "")
<< endl;
}
return out;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_COMMENT_HH

View File

@ -0,0 +1,200 @@
#ifndef EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
#define EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
#include <iosfwd>
#include <string>
#include "eo_types.hh"
#include "tab.hh"
#include "comment.hh"
#include "parameters_generator.hh"
namespace efl { namespace eolian { namespace grammar {
struct class_name
{
std::string _name;
class_name(std::string name)
: _name(name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, class_name const& x)
{
out << x._name;
return out;
}
struct class_extensions
{
eo_class const& _cls;
class_extensions(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, class_extensions const& x)
{
eo_class const& cls = x._cls;
extensions_container_type::const_iterator it, first = cls.extensions.begin();
extensions_container_type::const_iterator last = cls.extensions.end();
for (it = first; it != last; ++it)
{
if (it != first) out << ",";
out << tab(2)
<< "efl::eo::detail::extension_inheritance<"
<< *it << ">::type<"
<< cls.name << ">";
}
out << endl;
return out;
}
struct class_inheritance
{
eo_class const& _cls;
class_inheritance(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, class_inheritance const& x)
{
eo_class const& cls = x._cls;
out << class_name(cls.parent);
if (cls.extensions.size() > 0)
{
out << "," << endl << class_extensions(cls);
}
out << endl;
return out;
}
struct constructor_eo
{
eo_class const& _cls;
constructor_eo(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, constructor_eo const& x)
{
std::string doc = "@brief Eo Constructor.\n\n"
"Constructs the object from an Eo* pointer stealing its ownership.\n\n"
"@param eo The Eo object pointer.\n\n";
out << comment(doc, 1)
<< tab(1)
<< "explicit " << x._cls.name << "(Eo* eo)" << endl
<< tab(2) << ": " << class_name(x._cls.parent) << "(eo)" << endl
<< tab(1) << "{}" << endl << endl;
return out;
}
struct constructors
{
eo_class const& _cls;
constructors(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, constructors const& x)
{
constructors_container_type::const_iterator it,
first = x._cls.constructors.cbegin(),
last = x._cls.constructors.cend();
for (it = first; it != last; ++it)
{
eo_constructor const& ctor = *it;
out << comment(ctor.comment, 1)
<< tab(1)
<< x._cls.name
<< '(' << parameters_declaration(ctor.params)
<< (ctor.params.size() > 0 ? ", " : "")
<< "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
<< tab(2) << ": " << class_name(x._cls.name)
<< "(_c" << (it - first) << "(" << parameters_list(ctor.params)
<< (ctor.params.size() > 0 ? ", " : "")
<< "_p))" << endl
<< tab(1) << "{}" << endl << endl;
}
return out;
}
struct copy_constructor
{
eo_class const& _cls;
copy_constructor(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, copy_constructor const& x)
{
std::string doc = "@brief Copy Constructor.\n\n";
out << comment(doc, 1)
<< tab(1)
<< x._cls.name << "(" << x._cls.name << " const& other)" << endl
<< tab(2) << ": " << class_name(x._cls.parent)
<< "(eo_ref(other._eo_ptr()))" << endl
<< tab(1) << "{}" << endl << endl;
return out;
}
struct destructor
{
eo_class const& _cls;
destructor(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, destructor const& x)
{
out << tab(1)
<< '~' << x._cls.name << "() {}" << endl << endl;
return out;
}
struct eo_class_constructors
{
eo_class const& _cls;
eo_class_constructors(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, eo_class_constructors const& x)
{
constructors_container_type::const_iterator it,
first = x._cls.constructors.begin(),
last = x._cls.constructors.end();
for (it = first; it != last; ++it)
{
out << tab(1)
<< "static Eo* _c" << (it - first) << "("
<< parameters_declaration((*it).params)
<< ((*it).params.size() > 0 ? ", " : "")
<< "efl::eo::parent_type _p"
<< ')' << endl
<< tab(1) << "{" << endl
<< tab(2) << "return eo_add_custom("
<< x._cls.eo_name << ", _p._eo_raw, " << (*it).name
<< "(" << parameters_list((*it).params) << "));" << endl
<< tab(1) << "}" << endl << endl;
}
return out;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH

View File

@ -0,0 +1,95 @@
#ifndef EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH
#define EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH
#include <iosfwd>
#include <algorithm> // std::transform()
#include <ctype.h> // ::toupper()
#include "eo_types.hh"
#include "tab.hh"
#include "comment.hh"
#include "parameters_generator.hh"
namespace efl { namespace eolian { namespace grammar {
struct event_callback_add
{
eo_event const& _event;
std::string const& _ev_name;
event_callback_add(eo_event const& event, std::string const& ev_name)
: _event(event),
_ev_name(ev_name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, event_callback_add const& x)
{
// TODO implement
return out;
}
struct event_callback_del
{
eo_event const& _event;
std::string const& _ev_name;
event_callback_del(eo_event const& event, std::string const& ev_name)
: _event(event),
_ev_name(ev_name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, event_callback_del const& x)
{
// TODO: implement
return out;
}
struct event_callback_call
{
eo_event const& _event;
std::string const& _ev_name;
event_callback_call(eo_event const& event, std::string const& ev_name)
: _event(event),
_ev_name(ev_name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, event_callback_call const& x)
{
// TODO implement
return out;
}
struct events
{
events_container_type const& _events;
events(events_container_type const& events) : _events(events) {}
};
inline std::ostream&
operator<<(std::ostream& out, events const& x)
{
std::string prefix = x._cls.name + "_EVENT_";
std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper());
events_container_type::const_iterator it,
first = x._events.begin(),
last = x._events.end();
for (it = first; it != last; ++it)
{
std::string ev_name = (*it).name;
std::transform(ev_name.begin(), ev_name.end(), ev_name.begin(), ::toupper());
out << event_callback_add((*it), prefix+ev_name)
<< event_callback_del((*it), prefix+ev_name)
<< event_callback_call((*it), prefix+ev_name);
}
return out;
}
} } }
#endif // EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH

View File

@ -0,0 +1,84 @@
#ifndef EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH
#define EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH
#include <iosfwd>
#include "eo_types.hh"
#include "tab.hh"
#include "comment.hh"
#include "parameters_generator.hh"
namespace efl { namespace eolian { namespace grammar {
struct function_call
{
eo_function const& _func;
function_call(eo_function const& func) : _func(func) {}
};
inline std::ostream&
operator<<(std::ostream& out, function_call const& x)
{
bool is_void = function_is_void(x._func);
out << (!is_void ? "_tmp_ret = " : "")
<< "::" << x._func.impl
<< "(" << parameters_list(x._func.params) << ")";
return out;
}
struct function
{
eo_function const& _func;
function(eo_function const& func) : _func(func) {}
};
inline std::ostream&
operator<<(std::ostream& out, function const& x)
{
eo_function const& func = x._func;
bool is_void = function_is_void(func);
out << comment(x._func.comment, 1)
<< tab(1)
<< ( func.type == eo_function::class_ ? "static " : "" )
<< func.ret << " " << func.name << "("
<< parameters_declaration(func.params)
<< ") const" << endl
<< tab(1) << "{" << endl;
if (!is_void)
{
out << tab(2) << func.ret << " _tmp_ret;" << endl;
}
out << tab(2) << "eo_do(_eo_ptr(), "
<< function_call(x._func)
<< ");" << endl;
if (!is_void)
{
out << tab(2) << "return _tmp_ret;" << endl;
}
out << tab(1) << "}" << endl;
return out;
}
struct functions
{
functions_container_type const& _funcs;
functions(functions_container_type const& funcs) : _funcs(funcs) {}
};
inline std::ostream&
operator<<(std::ostream& out, functions const& x)
{
functions_container_type::const_iterator it,
first = x._funcs.begin(),
last = x._funcs.end();
for (it = first; it != last; it++)
{
out << function(*it) << endl;
}
return out;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH

View File

@ -0,0 +1,52 @@
#ifndef EOLIAN_CXX_EO_CLASS_GENERATOR_HH
#define EOLIAN_CXX_EO_CLASS_GENERATOR_HH
#include <iosfwd>
#include <string>
#include "eo_types.hh"
#include "tab.hh"
#include "comment.hh"
#include "eo_class_constructors_generator.hh"
#include "eo_class_functions_generator.hh"
namespace efl { namespace eolian { namespace grammar {
struct eo_class_getter
{
eo_class const& _cls;
eo_class_getter(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, eo_class_getter const& x)
{
out << tab(1) << "static Eo_Class const* _eo_class()" << endl
<< tab(1) << "{" << endl
<< tab(2) << "return("<< x._cls.eo_name << ");" << endl
<< tab(1) << "}" << endl << endl;
return out;
}
inline void
eo_class_generator(std::ostream& out, eo_class const& cls)
{
out << comment(cls.comment)
<< "struct " << cls.name << endl
<< tab(2) << ": " << class_inheritance(cls)
<< '{' << endl
<< constructor_eo(cls)
<< constructors(cls)
<< copy_constructor(cls)
<< destructor(cls)
<< functions(cls.functions)
<< eo_class_getter(cls)
<< "private:" << endl
<< eo_class_constructors(cls)
<< "};" << endl;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_EO_CLASS_GENERATOR_HH

View File

@ -0,0 +1,120 @@
#ifndef EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH
#define EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH
#include <algorithm>
#include <string>
#include <iosfwd>
#include <ctype.h>
#include "eo_types.hh"
#include "tab.hh"
#include "eo_class_generator.hh"
#include "inheritance_base_generator.hh"
namespace {
std::string
_onceguard_key(efl::eolian::eo_class const& cls)
{
std::string key;
if (cls.name_space != "")
{
std::string ns = cls.name_space;
size_t pos = 0;
while ((pos = ns.find("::")) != std::string::npos)
{
key += ns.substr(0, pos) + "_";
ns.erase(0, pos+2);
}
key += ns + "_";
}
key += cls.name;
std::transform(key.begin(), key.end(), key.begin(), ::toupper);
return key;
}
}
namespace efl { namespace eolian { namespace grammar {
inline void
onceguard_head(std::ostream& out, eo_class const& cls)
{
std::string key = ::_onceguard_key(cls);
out << "#ifndef EFL_GENERATED_" << key << "_HH" << endl
<< "#define EFL_GENERATED_" << key << "_HH" << endl << endl;
}
inline void
onceguard_tail(std::ostream& out, eo_class const& cls)
{
std::string key = ::_onceguard_key(cls);
out << "#endif // EFL_GENERATED_" << key << "_HH" << endl;
}
inline void
namespace_head(std::ostream& out, eo_class const& cls)
{
if (cls.name_space != "")
{
std::string ns = cls.name_space;
size_t pos = 0;
while ((pos = ns.find("::")) != std::string::npos)
{
out << "namespace " << ns.substr(0, pos) << " { ";
ns.erase(0, pos+2);
}
out << "namespace " << ns << " { " << endl << endl;
}
}
inline void
namespace_tail(std::ostream& out, eo_class const& cls)
{
if (cls.name_space != "")
{
std::string ns = cls.name_space;
size_t pos = 0;
while ((pos = ns.find("::")) != std::string::npos)
{
out << "} ";
ns.erase(0, pos+2);
}
out << "} " << endl << endl;
}
}
inline void
include_headers(std::ostream& out, eo_generator_options const& opts)
{
out << "#include <Eo.h>" << endl
<< "#include <Eo.hh>" << endl << endl
<< "extern \"C\"" << endl
<< "{" << endl;
for (auto c_header : opts.c_headers)
{
out << "#include \"" << c_header << "\"" << endl;
}
out << "}" << endl << endl;
for (auto cxx_header : opts.cxx_headers)
{
out << "#include \"" << cxx_header << "\"" << endl;
}
out << endl;
}
inline void
eo_header_generator(std::ostream& out, eo_class const& cls, eo_generator_options const& opts)
{
onceguard_head(out, cls);
include_headers(out, opts);
namespace_head(out, cls);
eo_class_generator(out, cls);
namespace_tail(out, cls);
eo_inheritance_detail_generator(out, cls);
onceguard_tail(out, cls);
out << endl;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH

View File

@ -0,0 +1,382 @@
#ifndef EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH
#define EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH
#include <iosfwd>
#include <cassert>
#include <algorithm>
#include "eo_types.hh"
#include "tab.hh"
#include "parameters_generator.hh"
#include "eo_class_functions_generator.hh"
namespace efl { namespace eolian { namespace grammar {
struct inheritance_operation
{
eo_class const& _cls;
functions_container_type::size_type _idx;
inheritance_operation(eo_class const& cls, functions_container_type::size_type idx)
: _cls(cls), _idx(idx)
{}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_operation const& x)
{
assert(x._idx < x._cls.functions.size());
eo_function const& func = x._cls.functions[x._idx];
out << tab(1)
<< "ops[" << x._idx << "].func = reinterpret_cast<void*>(& ::"
<< x._cls.name << "_" << func.name << "_wrapper<T>);" << endl
<< tab(1) << "ops[" << x._idx << "].api_func = reinterpret_cast<void*>(& ::"
<< func.impl << ");" << endl
<< tab(1) << "ops[" << x._idx << "].op = EO_OP_OVERRIDE;" << endl
<< tab(1) << "ops[" << x._idx << "].op_type = EO_OP_TYPE_REGULAR;" << endl // XXX class ops
<< tab(1) << "ops[" << x._idx << "].doc = NULL;" << endl
<< endl;
return out;
}
struct inheritance_operations_description
{
eo_class const& _cls;
inheritance_operations_description(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_operations_description const& x)
{
out << "template <typename T>"
<< endl << "int initialize_operation_description(efl::eo::detail::tag<"
<< x._cls.name_space << "::" << x._cls.name << ">" << endl
<< tab(11)
<< ", Eo_Op_Description* ops)" << endl
<< "{" << endl
<< tab(1) << "(void)ops;" << endl;
functions_container_type::size_type n_ops = x._cls.functions.size();
for (functions_container_type::size_type i=0; i < n_ops; ++i)
{
out << inheritance_operation(x._cls, i);
}
out << tab(1) << "return 0;" << endl
<< "}" << endl;
return out;
}
struct inheritance_wrapper
{
eo_class const& _cls;
eo_function const& _func;
inheritance_wrapper(eo_class const& cls, eo_function const& func)
: _cls(cls), _func(func)
{}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_wrapper const& x)
{
out << "template <typename T>" << endl
<< x._func.ret << " " << x._cls.name << "_" << x._func.name
<< "_wrapper(Eo* objid EINA_UNUSED, "
<< "efl::eo::detail::Inherit_Private_Data* self"
<< (x._func.params.size() ? ", " : "")
<< parameters_declaration(x._func.params)
<< ")" << endl
<< "{" << endl
<< tab(1)
<< (!function_is_void(x._func) ? "return ": "")
<< "static_cast<T*>(self->this_)->"
<< x._func.name << "(" << parameters_list(x._func.params) << ");" << endl
<< "}" << endl << endl;
return out;
}
struct inheritance_wrappers
{
eo_class const& _cls;
inheritance_wrappers(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_wrappers const& x)
{
functions_container_type::const_iterator it,
first = x._cls.functions.begin(),
last = x._cls.functions.end();
for (it = first; it != last; ++it)
{
eo_function const& func = *it;
out << "template <typename T>" << endl
<< func.ret << " " << x._cls.name << "_" << func.name
<< "_wrapper(Eo* objid EINA_UNUSED, "
<< "efl::eo::detail::Inherit_Private_Data* self"
<< (func.params.size() ? ", " : "")
<< parameters_declaration(func.params)
<< ")" << endl
<< "{" << endl
<< tab(1)
<< (!function_is_void(func) ? "return ": "")
<< "static_cast<T*>(self->this_)->"
<< func.name << "(" << parameters_list(func.params) << ");" << endl
<< "}" << endl << endl;
}
return out;
}
struct inheritance_base_operations_size
{
eo_class const& _cls;
inheritance_base_operations_size(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_base_operations_size const& x)
{
out << "template<>"
<< endl << "struct operation_description_class_size< "
<< x._cls.name_space << "::" << x._cls.name << " >" << endl
<< "{" << endl
<< tab(1) << "static const int value = "
<< x._cls.functions.size()
<< ";" << endl
<< "};" << endl
<< endl;
return out;
}
struct inheritance_base_operations_function
{
eo_class const& _cls;
eo_function const& _func;
inheritance_base_operations_function(eo_class const& cls, eo_function const& func)
: _cls(cls) , _func(func)
{}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_base_operations_function const& x)
{
eo_function const& func = x._func;
bool is_void = function_is_void(func);
out << tab(2) << "virtual " << func.ret << " "
<< func.name << "("
<< parameters_declaration(func.params) << ")" << endl
<< tab(2) << "{" << endl;
if (!is_void)
{
out << tab(3) << func.ret << " _tmp_ret = {};" << endl;
}
out << tab(3)
<< "eo_do_super(static_cast<T*>(this)->_eo_ptr()" << endl
<< tab(4) << ", static_cast<T*>(this)->_eo_class()" << endl
<< tab(4) << ", " << function_call(func)
<< ");" << endl;
if (!is_void)
{
out << tab(3) << "return _tmp_ret;" << endl;
}
out << tab(2) << "}" << endl << endl;
return out;
}
struct inheritance_base_operations
{
eo_class const& _cls;
inheritance_base_operations(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_base_operations const& x)
{
out << "template<>" << endl
<< "struct operations< "
<< x._cls.name_space << "::" << x._cls.name << " >" << endl
<< "{" << endl
<< tab(1) << "template <typename T>" << endl
<< tab(1) << "struct type" << endl
<< tab(1) << "{" << endl;
functions_container_type::const_iterator it,
first = x._cls.functions.begin(),
last = x._cls.functions.end();
for (it = first; it != last; ++it)
{
out << inheritance_base_operations_function(x._cls, *it);
}
out << tab(1) << "};" << endl
<< "};" << endl << endl;
return out;
}
struct inheritance_call_constructor_arguments
{
parameters_container_type const& _params;
inheritance_call_constructor_arguments(parameters_container_type const& params)
: _params(params)
{}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_call_constructor_arguments const& x)
{
parameters_container_type::size_type i, n = x._params.size();
for (i=0; i<n; i++)
{
if(i!=0) out << ", ";
out << "args.get<" << i << ">()";
}
return out;
}
struct inheritance_call_constructors
{
eo_class const& _cls;
inheritance_call_constructors(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_call_constructors const& x)
{
constructors_container_type::const_iterator it,
first = x._cls.constructors.begin(),
last = x._cls.constructors.end();
for (it = first; it != last; ++it)
{
eo_constructor const& ctor = *it;
out << "inline void" << endl
<< "call_constructor(tag< "
<< x._cls.name_space << "::" << x._cls.name << " >" << endl
<< tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl
<< tab(5) << "args_class<"
<< x._cls.name_space << "::" << x._cls.name
<< ", ::std::tuple<"
<< parameters_types(ctor.params)
<< "> > const& args)" << endl
<< "{" << endl
<< tab(1) << "(void)args;" << endl
<< tab(1)
<< "eo_do_super(eo, cls, ::" << ctor.name
<< "(" << inheritance_call_constructor_arguments(ctor.params)
<< "));" << endl
<< "}" << endl << endl;
}
return out;
}
struct inheritance_extension_function
{
eo_function const& _func;
inheritance_extension_function(eo_function const& func) : _func(func) {}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_extension_function const& x)
{
bool is_void = function_is_void(x._func);
out << tab(2)
<< x._func.ret << " "
<< x._func.name << "("
<< parameters_declaration(x._func.params)
<< ")" << endl
<< tab(2) << "{" << endl;
if (!is_void)
{
out << tab(3) << x._func.ret << " _tmp_ret = {};" << endl;
}
out << tab(3) << "eo_do(static_cast<T*>(this)->_eo_ptr(), "
<< function_call(x._func) << ");" << endl;
if (!is_void)
{
out << tab(3) << "return _tmp_ret;" << endl;
}
out << tab(2) << "}" << endl
<< endl;
return out;
}
struct inheritance_extension
{
eo_class const& _cls;
inheritance_extension(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_extension const& x)
{
std::string cls = x._cls.name_space + "::" + x._cls.name;
out << "template<>" << endl
<< "struct extension_inheritance< "
<< cls << ">" << endl
<< "{" << endl
<< tab(1) << "template <typename T>" << endl
<< tab(1) << "struct type" << endl
<< tab(1) << "{" << endl
<< tab(2) << "operator " << cls << "() const" << endl
<< tab(2) << "{" << endl
<< tab(3) << "return " << cls
<< "(eo_ref(static_cast<T const*>(this)->_eo_ptr()));" << endl
<< tab(2) << "}" << endl
<< endl;
functions_container_type::const_iterator it,
first = x._cls.functions.begin(),
last = x._cls.functions.end();
for (it = first; it != last; ++it)
{
out << inheritance_extension_function(*it);
}
out << tab(1) << "};" << endl
<< "};" << endl
<< endl;
return out;
}
struct inheritance_eo_class_getter
{
eo_class const& _cls;
inheritance_eo_class_getter(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, inheritance_eo_class_getter const& x)
{
out << "inline Eo_Class const* get_eo_class(tag<"
<< x._cls.name_space << "::" << x._cls.name << ">)" << endl
<< "{" << endl
<< tab(1) << "return (" << x._cls.eo_name << ");" << endl
<< "}" << endl << endl;
return out;
}
inline void
eo_inheritance_detail_generator(std::ostream& out, eo_class const& cls)
{
out << inheritance_wrappers(cls)
<< "namespace efl { namespace eo { namespace detail {" << endl << endl
<< inheritance_base_operations(cls) << endl
<< inheritance_base_operations_size(cls)
<< inheritance_operations_description(cls)
<< inheritance_call_constructors(cls)
<< inheritance_extension(cls)
<< inheritance_eo_class_getter(cls)
<< "} } }" << endl;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH

View File

@ -0,0 +1,82 @@
#ifndef EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH
#define EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH
#include <iosfwd>
#include "tab.hh"
#include "eo_types.hh"
namespace efl { namespace eolian { namespace grammar {
struct
parameters_declaration
{
parameters_container_type const& _params;
parameters_declaration(parameters_container_type const& params)
: _params(params)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameters_declaration const& x)
{
parameters_container_type::const_iterator it, first = x._params.cbegin();
parameters_container_type::const_iterator last = x._params.cend();
for (it = first; it != last; ++it)
{
if (it != first) out << ", ";
out << (*it).type << " " << (*it).name;
}
return out;
}
struct
parameters_types
{
parameters_container_type const& _params;
parameters_types(parameters_container_type const& params)
: _params(params)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameters_types const& x)
{
parameters_container_type::const_iterator it,
first = x._params.begin(),
last = x._params.end();
for (it = first; it != last; ++it)
{
if(it != first) out << ", ";
out << (*it).type;
}
return out;
}
struct
parameters_list
{
parameters_container_type const& _params;
parameters_list(parameters_container_type const& params)
: _params(params)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameters_list const& x)
{
parameters_container_type::const_iterator it, first = x._params.cbegin();
parameters_container_type::const_iterator last = x._params.cend();
for (it = first; it != last; ++it)
{
if (it != first) out << ", ";
out << (*it).name;
}
return out;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH

View File

@ -0,0 +1,52 @@
#ifndef EOLIAN_CXX_STD_TAB_HH
#define EOLIAN_CXX_STD_TAB_HH
#include <iosfwd>
#include <ostream>
#include <sstream>
namespace efl { namespace eolian { namespace grammar {
using std::endl;
const int tabsize = 3;
struct tab
{
int _n;
tab(int n) : _n(n * tabsize) {}
};
inline std::ostream&
operator<<(std::ostream& out, efl::eolian::grammar::tab tab)
{
for (int i = tab._n; i; --i)
out << ' ';
return out;
}
struct tabify
{
int _n;
std::string _text;
tabify(int n, std::string const& text)
: _n(n), _text(text)
{}
};
inline std::ostream&
operator<<(std::ostream& out, efl::eolian::grammar::tabify const& x)
{
std::string line, tab(tabsize*x._n, ' ');
std::istringstream ss(x._text);
while (std::getline(ss, line))
{
out << tab << line << endl;
}
return out;
}
} } }
#endif // EOLIAN_CXX_STD_TAB_HH

View File

@ -2,3 +2,4 @@ check-results.xml
*_suite
*_suite.log
*_suite.trs
*/cxx_compile_test

View File

@ -0,0 +1,14 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Ecore_Audio.h>
#include <Ecore_Audio.hh>
#include <iostream>
int main()
{
std::cout << "Ecore Audio C++ headers compile";
return 0;
}

View File

@ -0,0 +1,13 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "Ecore.hh"
#include <iostream>
int main()
{
std::cout << "Ecore C++ headers compile";
return 0;
}

View File

@ -0,0 +1,14 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Edje.h>
#include <Edje.hh>
#include <iostream>
int main()
{
std::cout << "Edje C++ headers compile";
return 0;
}

View File

@ -0,0 +1,15 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Evas.h>
#include <Evas.hh>
#include <iostream>
int main()
{
std::cout << "Evas C++ headers compile";
return 0;
}