diff --git a/.gitignore b/.gitignore index 5589fb4262..d6fec93084 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/Makefile.am b/Makefile.am index 12aa04464c..4bdb0775bc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/cmakeconfig/EcoreCxxConfig.cmake.in b/cmakeconfig/EcoreCxxConfig.cmake.in new file mode 100644 index 0000000000..4dcd580286 --- /dev/null +++ b/cmakeconfig/EcoreCxxConfig.cmake.in @@ -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) diff --git a/cmakeconfig/EetCxxConfig.cmake.in b/cmakeconfig/EetCxxConfig.cmake.in new file mode 100644 index 0000000000..18b0713340 --- /dev/null +++ b/cmakeconfig/EetCxxConfig.cmake.in @@ -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) diff --git a/cmakeconfig/EinaCxxConfig.cmake.in b/cmakeconfig/EinaCxxConfig.cmake.in new file mode 100644 index 0000000000..f2f5658b63 --- /dev/null +++ b/cmakeconfig/EinaCxxConfig.cmake.in @@ -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) diff --git a/cmakeconfig/EoCxxConfig.cmake.in b/cmakeconfig/EoCxxConfig.cmake.in new file mode 100644 index 0000000000..94a9790da9 --- /dev/null +++ b/cmakeconfig/EoCxxConfig.cmake.in @@ -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) diff --git a/cmakeconfig/EolianCxxConfig.cmake.in b/cmakeconfig/EolianCxxConfig.cmake.in new file mode 100644 index 0000000000..2f7101f0a7 --- /dev/null +++ b/cmakeconfig/EolianCxxConfig.cmake.in @@ -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) diff --git a/cmakeconfig/EvasCxxConfig.cmake.in b/cmakeconfig/EvasCxxConfig.cmake.in new file mode 100644 index 0000000000..e45e111646 --- /dev/null +++ b/cmakeconfig/EvasCxxConfig.cmake.in @@ -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) diff --git a/configure.ac b/configure.ac index c72bb32dbb..40e297e4e9 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/pc/.gitignore b/pc/.gitignore index ae42f58ef3..f872dd524e 100644 --- a/pc/.gitignore +++ b/pc/.gitignore @@ -52,3 +52,7 @@ /evas.pc /evil.pc /eolian.pc +/eolian-cxx.pc +/eo-cxx.pc +/evas-cxx.pc +/ecore-audio-cxx.pc.in diff --git a/pc/eet-cxx.pc.in b/pc/eet-cxx.pc.in index 2412c487a3..23d2bbb986 100644 --- a/pc/eet-cxx.pc.in +++ b/pc/eet-cxx.pc.in @@ -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 diff --git a/pc/eina-cxx.pc.in b/pc/eina-cxx.pc.in index c6571fa4ae..4063866443 100644 --- a/pc/eina-cxx.pc.in +++ b/pc/eina-cxx.pc.in @@ -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 diff --git a/pc/eo-cxx.pc.in b/pc/eo-cxx.pc.in new file mode 100644 index 0000000000..a44e7f9ab6 --- /dev/null +++ b/pc/eo-cxx.pc.in @@ -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@ diff --git a/pc/eolian-cxx.pc.in b/pc/eolian-cxx.pc.in new file mode 100644 index 0000000000..1dad9f2d6d --- /dev/null +++ b/pc/eolian-cxx.pc.in @@ -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@ diff --git a/pc/evas-cxx.pc.in b/pc/evas-cxx.pc.in new file mode 100644 index 0000000000..eb22b99937 --- /dev/null +++ b/pc/evas-cxx.pc.in @@ -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@ + diff --git a/src/Makefile.am b/src/Makefile.am index 60d4b3d40e..2e9a133900 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/Makefile_Ecore_Audio_Cxx.am b/src/Makefile_Ecore_Audio_Cxx.am new file mode 100644 index 0000000000..edf23a9500 --- /dev/null +++ b/src/Makefile_Ecore_Audio_Cxx.am @@ -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 diff --git a/src/Makefile_Ecore_Cxx.am b/src/Makefile_Ecore_Cxx.am index ff8efdca86..ec2b64a4c2 100644 --- a/src/Makefile_Ecore_Cxx.am +++ b/src/Makefile_Ecore_Cxx.am @@ -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 diff --git a/src/Makefile_Edje_Cxx.am b/src/Makefile_Edje_Cxx.am new file mode 100644 index 0000000000..094855dbb7 --- /dev/null +++ b/src/Makefile_Edje_Cxx.am @@ -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 diff --git a/src/Makefile_Eet_Cxx.am b/src/Makefile_Eet_Cxx.am index b2381aaeda..4686de6c4e 100644 --- a/src/Makefile_Eet_Cxx.am +++ b/src/Makefile_Eet_Cxx.am @@ -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 \ diff --git a/src/Makefile_Eo_Cxx.am b/src/Makefile_Eo_Cxx.am new file mode 100644 index 0000000000..d33c77c901 --- /dev/null +++ b/src/Makefile_Eo_Cxx.am @@ -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 diff --git a/src/Makefile_Eolian_Cxx.am b/src/Makefile_Eolian_Cxx.am new file mode 100644 index 0000000000..301f051ebb --- /dev/null +++ b/src/Makefile_Eolian_Cxx.am @@ -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) diff --git a/src/Makefile_Eolian_Cxx_Helper.am b/src/Makefile_Eolian_Cxx_Helper.am new file mode 100644 index 0000000000..3c85669074 --- /dev/null +++ b/src/Makefile_Eolian_Cxx_Helper.am @@ -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) diff --git a/src/Makefile_Evas_Cxx.am b/src/Makefile_Evas_Cxx.am new file mode 100644 index 0000000000..5938223a45 --- /dev/null +++ b/src/Makefile_Evas_Cxx.am @@ -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 " >> $(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 diff --git a/src/bin/eolian_cxx/.gitignore b/src/bin/eolian_cxx/.gitignore new file mode 100644 index 0000000000..cfe67763b0 --- /dev/null +++ b/src/bin/eolian_cxx/.gitignore @@ -0,0 +1 @@ +/eolian_cxx diff --git a/src/bin/eolian_cxx/comments.cc b/src/bin/eolian_cxx/comments.cc new file mode 100644 index 0000000000..afe725f300 --- /dev/null +++ b/src/bin/eolian_cxx/comments.cc @@ -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(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 diff --git a/src/bin/eolian_cxx/comments.hh b/src/bin/eolian_cxx/comments.hh new file mode 100644 index 0000000000..3aaf7562ce --- /dev/null +++ b/src/bin/eolian_cxx/comments.hh @@ -0,0 +1,29 @@ + +#ifndef EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH +#define EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH + +#include + +extern "C" +{ +#include +#include +} + +#include + +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 diff --git a/src/bin/eolian_cxx/convert.cc b/src/bin/eolian_cxx/convert.cc new file mode 100644 index 0000000000..6672daa54f --- /dev/null +++ b/src/bin/eolian_cxx/convert.cc @@ -0,0 +1,304 @@ +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#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(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(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(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(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(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(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(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; +} diff --git a/src/bin/eolian_cxx/convert.hh b/src/bin/eolian_cxx/convert.hh new file mode 100644 index 0000000000..910d3a5dd8 --- /dev/null +++ b/src/bin/eolian_cxx/convert.hh @@ -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 diff --git a/src/bin/eolian_cxx/eo_read.h b/src/bin/eolian_cxx/eo_read.h new file mode 100644 index 0000000000..2ad332f410 --- /dev/null +++ b/src/bin/eolian_cxx/eo_read.h @@ -0,0 +1,62 @@ + +#ifndef EOLIAN_CXX_EOLIAN_HELPER_H +#define EOLIAN_CXX_EOLIAN_HELPER_H + +#include +#include +#include + +#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 */ diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc new file mode 100644 index 0000000000..c6d146205f --- /dev/null +++ b/src/bin/eolian_cxx/eolian_cxx.cc @@ -0,0 +1,337 @@ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +} + +#include +#include + +#include "eo_read.h" +#include "convert.hh" +#include "safe_strings.hh" + +namespace { + +// Program options. +struct options_type +{ + std::vector 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(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 + 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 The Eo class name to generate code for." << std::endl + << " -D, --out-dir Output directory where generated code will be written." << std::endl + << " -I, --in The source containing the .eo descriptions." << std::endl + << " -o, --out-file The output file name. [default: .eo.hh]" << std::endl + << " -n, --namespace 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; +} diff --git a/src/bin/eolian_cxx/safe_strings.hh b/src/bin/eolian_cxx/safe_strings.hh new file mode 100644 index 0000000000..61f7f9b58f --- /dev/null +++ b/src/bin/eolian_cxx/safe_strings.hh @@ -0,0 +1,28 @@ + +#ifndef EOLIAN_CXX_BIN_SAFE_STRINGS_HH +#define EOLIAN_CXX_BIN_SAFE_STRINGS_HH + +#include + +extern "C" +{ +#include +} + +/// @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 diff --git a/src/bindings/ecore_cxx/Ecore.hh b/src/bindings/ecore_cxx/Ecore.hh index ad9dcabbc4..81f1ac2873 100644 --- a/src/bindings/ecore_cxx/Ecore.hh +++ b/src/bindings/ecore_cxx/Ecore.hh @@ -10,6 +10,10 @@ #include #include +#ifdef EFL_BETA_API_SUPPORT +#include +#endif + namespace efl { namespace ecore { template diff --git a/src/bindings/eo_cxx/Eo.hh b/src/bindings/eo_cxx/Eo.hh new file mode 100644 index 0000000000..a324e1c43c --- /dev/null +++ b/src/bindings/eo_cxx/Eo.hh @@ -0,0 +1,9 @@ +#ifndef EFL_CXX_EO_HH +#define EFL_CXX_EO_HH + +#include +#include +#include +#include + +#endif // EFL_CXX_EO_HH diff --git a/src/bindings/eo_cxx/eo_base.hh b/src/bindings/eo_cxx/eo_base.hh new file mode 100644 index 0000000000..00b660efc1 --- /dev/null +++ b/src/bindings/eo_cxx/eo_base.hh @@ -0,0 +1,229 @@ + +/// +/// @file eo_base.hh +/// + +#ifndef EFL_CXX_EO_BASE_HH +#define EFL_CXX_EO_BASE_HH + +#include +#include +#include +#include + +#include "eo_ops.hh" + + +namespace efl { namespace eo { + +/// @addtogroup Efl_Cxx_API +/// @{ + +/// @brief A binding to the EO Base Class. +/// +/// This class implements C++ wrappers to all the EO Base +/// operations. +/// +struct base +{ + /// @brief Class constructor. + /// + /// @param eo The EO Object. + /// + /// efl::eo::base constructors semantics are that of stealing the + /// EO Object lifecycle management. Its constructors do not + /// increment the EO 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 EO Object stored in this + /// instance. + /// + /// @return A pointer to the opaque EO Object. + /// + 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 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 EO Object. +}; + +/// @brief Downcast @p U to @p T. +/// +/// @param T An EO C++ Class. +/// @param U An EO C++ Class. +/// +/// @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 +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 diff --git a/src/bindings/eo_cxx/eo_inherit.hh b/src/bindings/eo_cxx/eo_inherit.hh new file mode 100644 index 0000000000..66de0869e5 --- /dev/null +++ b/src/bindings/eo_cxx/eo_inherit.hh @@ -0,0 +1,137 @@ + +/// +/// @file eo_inherit.hh +/// + +#ifndef EFL_CXX_EO_INHERIT_HH +#define EFL_CXX_EO_INHERIT_HH + +#include +#include + +#include + +#include "eo_ops.hh" +#include "eo_private.hh" + +namespace efl { namespace eo { + +namespace detail { + +template +Eo_Class const* create_class(eina::index_sequence); + +template +void inherit_constructor(void* this_, Args args); + +} + +/// @addtogroup Efl_Cxx_API +/// @{ + +/// @brief Template-class that allows client code to inherit from +/// EO C++ Classes without the need to make explicit calls to +/// EO methods --- that would naturally be necessary to +/// register itself in the EO Subsystem. +/// +/// @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 Base +/// Class (@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 EO +/// Class within EO Subsystem. Each class is registered +/// only once upon instantiation of an object of its type. +/// +/// @note Function overriding is currently not supported. +/// +template +struct inherit; + +/// @} + +/// @addtogroup Efl_Cxx_API +/// @{ + +template +struct inherit + : detail::operations::template type > ... + , detail::conversion_operator, E>... +{ + /// @typedef inherit_base + /// + typedef inherit inherit_base; + + /// @brief Class constructor. + /// + /// @ref inherit has a "variadic" constructor implementation that + /// allows from zero to EFL_MAX_ARGS heterogeneous parameters. + /// + template + inherit(Args&& ... args) + { + typedef std::tuple::type...> tuple_type; + _eo_cls = detail::create_class (eina::make_index_sequence()); + _eo_raw = eo_add_custom + (_eo_cls, NULL, + detail::inherit_constructor + + (static_cast(this), tuple_type(std::move(args)...))); + } + + /// @brief Class destructor. + /// + ~inherit() + { + detail::unref(_eo_raw); + } + + /// @brief Gets the EO Object corresponding to this EO + /// C++ Object. + /// + /// @return A pointer to the EO Object. + /// + Eo* _eo_ptr() const { return _eo_raw; } + + /// @brief Gets the EO Class corresponding to this EO + /// C++ Class. + /// + /// @return A pointer to the EO Class. + /// + 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 EO Class. + Eo* _eo_raw; ///< The EO Object. +}; + +/// @} + +} } // namespace efl { namespace eo { + +#include "eo_inherit_bindings.hh" + +#endif // EFL_CXX_INHERIT_HH diff --git a/src/bindings/eo_cxx/eo_inherit_bindings.hh b/src/bindings/eo_cxx/eo_inherit_bindings.hh new file mode 100644 index 0000000000..cffaa4d588 --- /dev/null +++ b/src/bindings/eo_cxx/eo_inherit_bindings.hh @@ -0,0 +1,347 @@ + +#ifndef EFL_CXX_DETAIL_INHERIT_BINDINGS_HH +#define EFL_CXX_DETAIL_INHERIT_BINDINGS_HH + +#include +#include + +namespace efl { namespace eo { namespace detail { + +/// @addtogroup Efl_Cxx_Detail +/// @{ + +/// @internal +/// +/// @brief Invokes the EO C Constructor that corresponds to the +/// binded EO C++ Class. +/// +/// @param T The corresponding EO C++ Class +/// @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 EO C Object 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 EO C++ Class --- 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 EO C++ Class. +/// +/// @see efl::eo::detail::tag +/// +template +void call_constructor(efl::eo::detail::tag tag, Eo* eo, Eo_Class const* cls, Args args); + +/// @internal +/// +/// @brief Sums up the number of EO Operations of each class +/// passed as argument to the template. +/// +/// @see efl::eo::detail::operation_description_class_size +/// +template +struct operation_description_size; + +template +struct operation_description_size +{ + static const int value = operation_description_class_size::value + + operation_description_size::value; +}; + +template <> +struct operation_description_size<> +{ + static const int value = 0; +}; + +template +struct is_args_class : std::false_type +{ +}; + +template +struct is_args_class > + : std::true_type +{ +}; + +template +struct are_args_class; + +template <> +struct are_args_class > + : std::true_type +{ +}; + +template +struct are_args_class > + : std::integral_constant + ::value + && are_args_class >::value + > +{ +}; + +template +struct has_args_class : std::false_type +{ + typedef std::integral_constant index; +}; + +template +struct has_args_class, Args...> > + : std::true_type +{ + typedef detail::args_class type; + typedef std::integral_constant index; +}; + +template +struct has_args_class > + : has_args_class > +{ + typedef has_args_class > base_type; + typedef std::integral_constant + 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 EO C++ Class. +/// +template +struct call_constructor_aux +{ + template + static void do_(Args const&, Eo* eo, Eo_Class const* cls + , P, typename std::enable_if::type* = 0) + { + call_constructor(tag(), eo, cls, args_class >(std::tuple<>())); + } + + template + static void do_(Args const& args, Eo* eo, Eo_Class const* cls + , P, typename std::enable_if::type* = 0) + { + call_constructor(tag(), eo, cls, std::get(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 EO Object. + /// @param cls The opaque EO Class. + /// + template + static int do_(Args const& args, Eo* eo, Eo_Class const* cls) + { + static_assert(std::tuple_size::value <= N, ""); + static_assert(are_args_class::value, ""); + do_(args, eo, cls, has_args_class()); + return 0; + } +}; + +template +struct call_constructor_aux +{ + template + static void do_(Args const& args, Eo* eo, Eo_Class const* cls + , std::true_type) + { + static_assert(std::tuple_size::value == 1, ""); + static_assert(std::is_same + ::type::class_type + , T>::value, ""); + call_constructor(tag(), eo, cls, std::get<0u>(args)); + } + + template + static void do_(Args const& args, Eo* eo, Eo_Class const* cls + , std::false_type) + { + call_constructor(tag(), eo, cls, args_class(args)); + } + + template + static int do_(Args const& args, Eo* eo, Eo_Class const* cls) + { + do_(args, eo, cls, has_args_class()); + return 0; + } +}; + +template +void call_varargs(Args...) +{ +} + +/// @internal +/// +/// @brief The procedure that actually is invoked when the constructor +/// of @c D is sought from the EO Subsystem. +/// +/// @param obj The opaque EO Object. +/// @param self A pointer to @p obj's private data. +/// @param this_ A void pointer to the opaque EO Class --- +/// passed as user data. +/// @param args The arguments for the underlying constructor. +/// +template +void inherit_constructor_impl(Eo* obj, Inherit_Private_Data* self, void* this_, Args args) +{ + self->this_ = this_; + Eo_Class const* cls = static_cast*>(this_)->_eo_class(); + detail::call_varargs(detail::call_constructor_aux::do_(args, obj, cls) ...); +} + +/// @internal +/// +/// @brief Find the correct function for the "constructor" +/// operation and invoke it. +/// +/// @param this_ The user data to be passed to the resolved function. +/// @param args An heterogeneous sequence of arguments. +/// +template +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 + (static_cast(&detail::inherit_constructor)), + __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 +int initialize_operation_description(detail::tag, void*); + +template +struct +operation_description_index +{ + typedef std::tuple tuple_type; + static const std::size_t value = + detail::operation_description_size + < typename std::tuple_element + ::type >::value + + operation_description_index::value; +}; +template +struct +operation_description_index<0u, E...> +{ + static const std::size_t value = 0u; +}; + +/// @internal +/// +/// @brief This function is responsible for declaring a new EO C +/// Class representing @p D within EO Subsystem. +/// +/// @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 +Eo_Class const* create_class(eina::index_sequence) +{ + static const Eo_Class* my_class = NULL; + static Eo_Op_Description op_descs + [ detail::operation_description_size::value + 2 ]; + + op_descs[detail::operation_description_size::value].func = + reinterpret_cast + ( + static_cast + (&detail::inherit_constructor_impl) + ); + op_descs[detail::operation_description_size::value].api_func = + reinterpret_cast + ( + static_cast + (&detail::inherit_constructor) + ); + op_descs[detail::operation_description_size::value].op = EO_NOOP; + op_descs[detail::operation_description_size::value].op_type = EO_OP_TYPE_REGULAR; + op_descs[detail::operation_description_size::value].doc = NULL; + + op_descs[detail::operation_description_size::value+1].func = 0; + op_descs[detail::operation_description_size::value+1].api_func = 0; + op_descs[detail::operation_description_size::value+1].op = 0; + op_descs[detail::operation_description_size::value+1].op_type = EO_OP_TYPE_INVALID; + op_descs[detail::operation_description_size::value+1].doc = NULL; + + typedef inherit inherit_type; + using namespace detail; + call_varargs( + initialize_operation_description + (detail::tag(), + &op_descs[operation_description_index::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(class_desc); + } + return my_class; +} + +} } } // namespace efl { namespace eo { namespace detail { + +#endif // EFL_CXX_DETAIL_INHERIT_BINDINGS_HH diff --git a/src/bindings/eo_cxx/eo_init.hh b/src/bindings/eo_cxx/eo_init.hh new file mode 100644 index 0000000000..a1cb3c2aaa --- /dev/null +++ b/src/bindings/eo_cxx/eo_init.hh @@ -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 EO Subsystem. +/// +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 diff --git a/src/bindings/eo_cxx/eo_ops.hh b/src/bindings/eo_cxx/eo_ops.hh new file mode 100644 index 0000000000..091c725099 --- /dev/null +++ b/src/bindings/eo_cxx/eo_ops.hh @@ -0,0 +1,141 @@ + +#ifndef EFL_CXX_DETAIL_EO_OPS_HH +#define EFL_CXX_DETAIL_EO_OPS_HH + +extern "C" +{ +#include +} + +#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 diff --git a/src/bindings/eo_cxx/eo_private.hh b/src/bindings/eo_cxx/eo_private.hh new file mode 100644 index 0000000000..a2271733b3 --- /dev/null +++ b/src/bindings/eo_cxx/eo_private.hh @@ -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 EO C++ Class +/// @param Seq An heterogenous sequence of arguments. +/// +template +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 + typename std::remove_reference + < + typename std::tuple_element::type + >::type get() const + { + return std::get(_tuple); + } + + /// + /// TODO document. + /// + constexpr std::size_t size() const + { + return std::tuple_size::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 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 +Eo_Class const* do_eo_class_new(Eo_Class_Description& class_desc) +{ + return eo_class_new(&class_desc, get_eo_class(tag())..., (void*)NULL); +} + +template 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 EO C++ Class +/// +template +struct conversion_operator +{ + operator T() const + { + detail::ref(static_cast(this)->_eo_ptr()); + return T(static_cast(this)->_eo_ptr()); + } +}; + +/// @} + +} // namespace detail { + +template +detail::args_class > +args(A... arg) +{ + return detail::args_class >(std::tuple(arg...)); +} + +namespace detail { + +/// @addtogroup Efl_Cxx_Detail +/// @{ + +/// @internal +/// +/// @brief Provides all operations of type @p T. +/// +/// @param T An EO C++ Class +/// +/// There must be an unique specialization of this class for each +/// declared EO C++ Class. +/// +template struct operations; + +/// @internal +/// +/// @brief Provides the operations of an extension as well as its +/// conversion operator. +/// +/// @param T The EO C++ Extension +/// +/// There must be an unique specialization of @ref +/// efl::eo::detail::extension_inheritance for each known EO C++ +/// Extension -- i.e., @em Interfaces and @em Mixins. +/// +template +struct extension_inheritance {}; + +/// @internal +/// +/// @brief efl::eo::inherit's private data. +/// +struct Inherit_Private_Data +{ + void* this_; +}; + +/// @} + +} } } // namespace efl { namespace eo { namespace detail { + +#endif diff --git a/src/bindings/eo_cxx/eo_wref.hh b/src/bindings/eo_cxx/eo_wref.hh new file mode 100644 index 0000000000..4e2385f2d3 --- /dev/null +++ b/src/bindings/eo_cxx/eo_wref.hh @@ -0,0 +1,126 @@ + +/// +/// @file eo_wref.hh +/// + +#ifndef EFL_CXX_WREF_HH +#define EFL_CXX_WREF_HH + +#include + +#include "eo_ops.hh" + +namespace efl { namespace eo { + +/// @addtogroup Efl_Cxx_API +/// @{ + +/// @brief Weak references to an EO Object. +/// +template +struct wref { + + /// @brief Class constructor. + /// + /// @param obj The EO Object to be referenced. + /// + /// Create a weak reference to @p obj. + /// + explicit wref(Eo* obj) : _eo_wref(obj) + { + _add(); + } + + /// @brief Class constructor. + /// + /// @param obj The EO C++ Object 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 p = lock()) + _del(); + } + + /// @brief Try to acquire a strong reference to the underlying + /// EO Object. + /// + /// This function checks whether the weak reference still points to + /// a valid EO Object. 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 EO Object. Otherwise it returns + /// an empty eina::optional. + /// + eina::optional 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 p = lock()) + { + _add(); + } + else + { + _eo_wref = 0; + } + } + + /// @brief Assignment operator. + /// + wref& operator=(wref const& other) + { + _eo_wref = other._eo_wref; + if(eina::optional 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 diff --git a/src/examples/eolian_cxx/.gitignore b/src/examples/eolian_cxx/.gitignore new file mode 100644 index 0000000000..6ae19365d7 --- /dev/null +++ b/src/examples/eolian_cxx/.gitignore @@ -0,0 +1,3 @@ +/eolian_cxx_simple_01 +/eolian_cxx_inherit_01 +/eolian_cxx_evas_images diff --git a/src/examples/eolian_cxx/Makefile.am b/src/examples/eolian_cxx/Makefile.am new file mode 100644 index 0000000000..eec68a6a7f --- /dev/null +++ b/src/examples/eolian_cxx/Makefile.am @@ -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 diff --git a/src/examples/eolian_cxx/colourable.c b/src/examples/eolian_cxx/colourable.c new file mode 100644 index 0000000000..3e289583dd --- /dev/null +++ b/src/examples/eolian_cxx/colourable.c @@ -0,0 +1,165 @@ +#include + +#ifdef HAVE_CONFIG_H +# include +#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" diff --git a/src/examples/eolian_cxx/colourable.eo b/src/examples/eolian_cxx/colourable.eo new file mode 100644 index 0000000000..a708217a39 --- /dev/null +++ b/src/examples/eolian_cxx/colourable.eo @@ -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); + }; +}; diff --git a/src/examples/eolian_cxx/colourablesquare.c b/src/examples/eolian_cxx/colourablesquare.c new file mode 100644 index 0000000000..1eb190cf85 --- /dev/null +++ b/src/examples/eolian_cxx/colourablesquare.c @@ -0,0 +1,91 @@ +#include + +#ifdef HAVE_CONFIG_H +# include +#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" diff --git a/src/examples/eolian_cxx/colourablesquare.eo b/src/examples/eolian_cxx/colourablesquare.eo new file mode 100644 index 0000000000..d254151152 --- /dev/null +++ b/src/examples/eolian_cxx/colourablesquare.eo @@ -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. */ }; + }; +}; diff --git a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc new file mode 100644 index 0000000000..798b3a8cf5 --- /dev/null +++ b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc @@ -0,0 +1,69 @@ + +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "colourable.eo.hh" +#include "colourablesquare.eo.hh" + +#include + +using namespace efl; + +struct ColourableCircle + : efl::eo::inherit +{ + 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(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; +} diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc new file mode 100644 index 0000000000..363073a259 --- /dev/null +++ b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc @@ -0,0 +1,35 @@ +// EINA_LOG_LEVELS=colourable:4,colourablesquare:4 ./eolian_cxx_simple_01 + +#include + +#ifdef HAVE_CONFIG_H +# include +#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; +} diff --git a/src/examples/evas/Makefile.am b/src/examples/evas/Makefile.am index eecd520d75..48fac12eeb 100644 --- a/src/examples/evas/Makefile.am +++ b/src/examples/evas/Makefile.am @@ -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 = \ diff --git a/src/examples/evas/evas_cxx_rectangle.cc b/src/examples/evas/evas_cxx_rectangle.cc new file mode 100644 index 0000000000..3b01071ccd --- /dev/null +++ b/src/examples/evas/evas_cxx_rectangle.cc @@ -0,0 +1,56 @@ + +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include +#include + +#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; +} diff --git a/src/lib/.gitignore b/src/lib/.gitignore index 62d9982fce..5ca060fe25 100644 --- a/src/lib/.gitignore +++ b/src/lib/.gitignore @@ -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 diff --git a/src/lib/eolian_cxx/Eolian_Cxx.hh b/src/lib/eolian_cxx/Eolian_Cxx.hh new file mode 100644 index 0000000000..c4fe6438a9 --- /dev/null +++ b/src/lib/eolian_cxx/Eolian_Cxx.hh @@ -0,0 +1,37 @@ + +#ifndef EOLIAN_CXX_LIB_HH +#define EOLIAN_CXX_LIB_HH + +extern "C" +{ +#include +#ifdef HAVE_CONFIG_H +# include +#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 diff --git a/src/lib/eolian_cxx/eo_generate.hh b/src/lib/eolian_cxx/eo_generate.hh new file mode 100644 index 0000000000..477f263159 --- /dev/null +++ b/src/lib/eolian_cxx/eo_generate.hh @@ -0,0 +1,20 @@ + +#ifndef EOLIAN_CXX_EO_GENERATE_HH +#define EOLIAN_CXX_EO_GENERATE_HH + +#include "eo_types.hh" + +#include +#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 diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh new file mode 100644 index 0000000000..1d04fd04b6 --- /dev/null +++ b/src/lib/eolian_cxx/eo_types.hh @@ -0,0 +1,89 @@ + +#ifndef EOLIAN_CXX_EO_TYPES_HH +#define EOLIAN_CXX_EO_TYPES_HH + +#include +#include + +namespace efl { namespace eolian { + +struct eo_constructor; +struct eo_parameter; +struct eo_function; +struct eo_event; + +typedef std::vector extensions_container_type; +typedef std::vector constructors_container_type; +typedef std::vector functions_container_type; +typedef std::vector parameters_container_type; +typedef std::vector events_container_type; + +struct eo_generator_options +{ + std::vector cxx_headers; + std::vector 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 diff --git a/src/lib/eolian_cxx/eo_validate.hh b/src/lib/eolian_cxx/eo_validate.hh new file mode 100644 index 0000000000..9e5342d55d --- /dev/null +++ b/src/lib/eolian_cxx/eo_validate.hh @@ -0,0 +1,91 @@ + +#ifndef EOLIAN_CXX_EO_CLASS_VALIDATE_HH +#define EOLIAN_CXX_EO_CLASS_VALIDATE_HH + +#include +#include + +#ifdef DEBUG +#include +#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 diff --git a/src/lib/eolian_cxx/grammar/comment.hh b/src/lib/eolian_cxx/grammar/comment.hh new file mode 100644 index 0000000000..f9853fb8c3 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/comment.hh @@ -0,0 +1,42 @@ + +#ifndef EOLIAN_CXX_STD_COMMENT_HH +#define EOLIAN_CXX_STD_COMMENT_HH + +#include +#include +#include + +#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 diff --git a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh new file mode 100644 index 0000000000..f434c560d0 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh @@ -0,0 +1,200 @@ + +#ifndef EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH +#define EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH + +#include +#include + +#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 diff --git a/src/lib/eolian_cxx/grammar/eo_class_events.generator.hh b/src/lib/eolian_cxx/grammar/eo_class_events.generator.hh new file mode 100644 index 0000000000..fdb3a317b7 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/eo_class_events.generator.hh @@ -0,0 +1,95 @@ + +#ifndef EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH +#define EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH + +#include + +#include // std::transform() +#include // ::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 diff --git a/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh new file mode 100644 index 0000000000..55675f36e6 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh @@ -0,0 +1,84 @@ + +#ifndef EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH +#define EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH + +#include + +#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 diff --git a/src/lib/eolian_cxx/grammar/eo_class_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_generator.hh new file mode 100644 index 0000000000..af92bb41a9 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/eo_class_generator.hh @@ -0,0 +1,52 @@ + +#ifndef EOLIAN_CXX_EO_CLASS_GENERATOR_HH +#define EOLIAN_CXX_EO_CLASS_GENERATOR_HH + +#include +#include + +#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 diff --git a/src/lib/eolian_cxx/grammar/eo_header_generator.hh b/src/lib/eolian_cxx/grammar/eo_header_generator.hh new file mode 100644 index 0000000000..875777c7ff --- /dev/null +++ b/src/lib/eolian_cxx/grammar/eo_header_generator.hh @@ -0,0 +1,120 @@ + +#ifndef EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH +#define EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH + +#include +#include +#include +#include + +#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 " << endl + << "#include " << 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 diff --git a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh new file mode 100644 index 0000000000..8cc25389a0 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh @@ -0,0 +1,382 @@ + +#ifndef EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH +#define EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH + +#include +#include +#include + +#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(& ::" + << x._cls.name << "_" << func.name << "_wrapper);" << endl + << tab(1) << "ops[" << x._idx << "].api_func = reinterpret_cast(& ::" + << 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 " + << 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 " << 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(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 " << 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(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(this)->_eo_ptr()" << endl + << tab(4) << ", static_cast(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 " << 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()"; + } + 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(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 " << 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(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 diff --git a/src/lib/eolian_cxx/grammar/parameters_generator.hh b/src/lib/eolian_cxx/grammar/parameters_generator.hh new file mode 100644 index 0000000000..644c1a58c9 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/parameters_generator.hh @@ -0,0 +1,82 @@ + +#ifndef EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH +#define EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH + +#include + +#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 diff --git a/src/lib/eolian_cxx/grammar/tab.hh b/src/lib/eolian_cxx/grammar/tab.hh new file mode 100644 index 0000000000..5cd31ba804 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/tab.hh @@ -0,0 +1,52 @@ + +#ifndef EOLIAN_CXX_STD_TAB_HH +#define EOLIAN_CXX_STD_TAB_HH + +#include +#include +#include + +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 diff --git a/src/tests/.gitignore b/src/tests/.gitignore index 184da5cc89..e69225df2e 100644 --- a/src/tests/.gitignore +++ b/src/tests/.gitignore @@ -2,3 +2,4 @@ check-results.xml *_suite *_suite.log *_suite.trs +*/cxx_compile_test diff --git a/src/tests/ecore_audio_cxx/cxx_compile_test.cc b/src/tests/ecore_audio_cxx/cxx_compile_test.cc new file mode 100644 index 0000000000..c1c3c4e081 --- /dev/null +++ b/src/tests/ecore_audio_cxx/cxx_compile_test.cc @@ -0,0 +1,14 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include + +int main() +{ + std::cout << "Ecore Audio C++ headers compile"; + return 0; +} diff --git a/src/tests/ecore_cxx/cxx_compile_test.cc b/src/tests/ecore_cxx/cxx_compile_test.cc new file mode 100644 index 0000000000..e249317e3b --- /dev/null +++ b/src/tests/ecore_cxx/cxx_compile_test.cc @@ -0,0 +1,13 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "Ecore.hh" + +#include + +int main() +{ + std::cout << "Ecore C++ headers compile"; + return 0; +} diff --git a/src/tests/edje_cxx/cxx_compile_test.cc b/src/tests/edje_cxx/cxx_compile_test.cc new file mode 100644 index 0000000000..3c0479c463 --- /dev/null +++ b/src/tests/edje_cxx/cxx_compile_test.cc @@ -0,0 +1,14 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include + +int main() +{ + std::cout << "Edje C++ headers compile"; + return 0; +} diff --git a/src/tests/evas_cxx/cxx_compile_test.cc b/src/tests/evas_cxx/cxx_compile_test.cc new file mode 100644 index 0000000000..d494ed6998 --- /dev/null +++ b/src/tests/evas_cxx/cxx_compile_test.cc @@ -0,0 +1,15 @@ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include + +int main() +{ + std::cout << "Evas C++ headers compile"; + return 0; +}