From a1f2db255b22052050baf0c04bb72146b22a6e99 Mon Sep 17 00:00:00 2001 From: Felipe Magno de Almeida Date: Wed, 18 Jan 2017 22:25:02 -0200 Subject: [PATCH] cxx: Modify how to generate C++ headers and allow cyclic dependencies Allow cyclic dependencies in generated C++ headers by changing order of includes and creating forward declarations. --- src/Makefile_Cxx.am | 111 +++++++-------- src/Makefile_Eolian_Cxx.am | 15 +- src/bin/eolian_cxx/eolian_cxx.cc | 129 +++++++++++++----- src/bindings/cxx/eldbus_cxx/Eldbus_Model.hh | 12 ++ src/bindings/cxx/eo_cxx/eo_cxx_interop.hh | 6 +- .../elementary/button_cxx_example_00.cc | 2 +- .../elementary/calendar_cxx_example_02.cc | 1 + .../eolian_cxx/eolian_cxx_inherit_01.cc | 2 + .../eolian_cxx/eolian_cxx_simple_01.cc | 2 + .../eolian_cxx_simple_01_cxx_impl.cc | 2 + src/lib/.gitignore | 13 +- src/lib/edje/Edje.hh | 9 ++ src/lib/efl/.gitignore | 1 - src/lib/efl/Efl.hh | 11 ++ src/lib/eio/Eio.hh | 9 ++ src/lib/elementary/.gitignore | 1 - src/lib/elementary/Elementary.hh | 26 ++++ .../eolian_cxx/grammar/class_declaration.hpp | 16 ++- src/lib/eolian_cxx/grammar/header.hpp | 3 +- .../implementation_include_directive.hpp | 6 + src/lib/eolian_cxx/grammar/keyword.hpp | 2 +- src/lib/eolian_cxx/grammar/klass_def.hpp | 54 ++++++++ src/lib/evas/Evas.hh | 9 ++ .../eolian_cxx/eolian_cxx_test_binding.cc | 2 + .../eolian_cxx/eolian_cxx_test_cyclic.cc | 7 + 25 files changed, 329 insertions(+), 122 deletions(-) create mode 100644 src/bindings/cxx/eldbus_cxx/Eldbus_Model.hh create mode 100644 src/lib/edje/Edje.hh create mode 100644 src/lib/efl/Efl.hh create mode 100644 src/lib/eio/Eio.hh create mode 100644 src/lib/elementary/Elementary.hh create mode 100644 src/lib/evas/Evas.hh diff --git a/src/Makefile_Cxx.am b/src/Makefile_Cxx.am index febc123dff..72d5713d46 100644 --- a/src/Makefile_Cxx.am +++ b/src/Makefile_Cxx.am @@ -21,63 +21,46 @@ bindings/cxx/eo_cxx/eo_private.hh ### Elementary C++ installed_elementarycxxmainheadersdir = $(includedir)/elementary-cxx-@VMAJ@/ nodist_installed_elementarycxxmainheaders_DATA = $(elementary_eolian_cxx_hh) $(elementary_eolian_cxx_impl_hh) \ -lib/elementary/Elementary.hh +lib/elementary/Elementary.eo.hh +dist_installed_elementarycxxmainheaders_DATA = lib/elementary/Elementary.hh -lib/elementary/Elementary.hh: $(elementary_eolian_cxx_hh) - @echo @ECHO_E@ "#ifndef EFL_CXX_ELEMENTARY_HH\n#define EFL_CXX_ELEMENTARY_HH\n" > $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#if defined(ELEMENTARY_H) || defined(ELM_WIDGET_H)" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#error Do not include Elm C API headers before including Elementary.hh" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#endif" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#ifndef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#define EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#ifndef EFL_EO_API_SUPPORT" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#define EFL_EO_API_SUPPORT" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#ifndef ELM_INTERNAL_API_ARGESFSDFEFC" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#define ELM_INTERNAL_API_ARGESFSDFEFC" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "extern \"C\" {" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#include \"Elementary.h\"" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "#include \"elm_widget.h\"" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "}" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @echo @ECHO_E@ "" >> $(top_builddir)/src/lib/elementary/Elementary.hh - @for i in $(elementary_eolian_cxx_hh); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/elementary/Elementary.hh; done - @echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/lib/elementary/Elementary.hh +lib/elementary/Elementary.eo.hh: $(elm_public_eolian_files) $(_EOLIAN_CXX_DEP) + $(AM_V_EOLCXX) \ + $(MKDIR_P) $(dir $@); \ + $(EOLIAN_CXX) $(EOLIAN_FLAGS) -m -o $@ $(filter %.eo, $^) -CLEANFILES += $(elementary_eolian_cxx_hh) $(elementary_eolian_cxx_impl_hh) lib/elementary/Elementary.hh +CLEANFILES += $(elementary_eolian_cxx_hh) $(elementary_eolian_cxx_impl_hh) lib/elementary/Elementary.eo.hh ### Efl C++ installed_eflcxxmainheadersdir = $(includedir)/efl-cxx-@VMAJ@/ -nodist_installed_eflcxxmainheaders_DATA = $(efl_eolian_cxx_hh) $(efl_eolian_cxx_impl_hh) lib/efl/Efl.hh +nodist_installed_eflcxxmainheaders_DATA = $(efl_eolian_cxx_hh) $(efl_eolian_cxx_impl_hh) lib/efl/Efl.eo.hh +dist_installed_eflcxxmainheaders_DATA = lib/efl/Efl.hh -lib/efl/Efl.hh: $(efl_eolian_cxx_hh) - @echo @ECHO_E@ "#ifndef EFL_CXX_HH\n#define EFL_CXX_HH\n" > $(top_builddir)/src/lib/efl/Efl.hh - @echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/efl/Efl.hh - @for i in $(efl_eolian_cxx_hh); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/efl/Efl.hh; done - @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/efl/Efl.hh +lib/efl/Efl.eo.hh: $(efl_eolian_files) $(_EOLIAN_CXX_DEP) + $(AM_V_EOLCXX) \ + $(MKDIR_P) $(dir $@); \ + $(EOLIAN_CXX) $(EOLIAN_FLAGS) -m -o $@ $(filter %.eo, $^) CLEANFILES += $(efl_eolian_cxx_hh) $(efl_eolian_cxx_impl_hh) lib/efl/Efl.hh ### Evas C++ installed_evascxxmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/ -nodist_installed_evascxxmainheaders_DATA = lib/evas/Evas.hh +dist_installed_evascxxmainheaders_DATA = lib/evas/Evas.hh +nodist_installed_evascxxmainheaders_DATA = lib/evas/Evas.eo.hh installed_evascxxcanvasheadersdir = $(includedir)/evas-cxx-@VMAJ@/canvas nodist_installed_evascxxcanvasheaders_DATA = $(evas_eolian_cxx_hh) $(evas_eolian_cxx_impl_hh) -lib/evas/Evas.hh: $(evas_eolian_cxx_hh) - @echo @ECHO_E@ "#ifndef EFL_CXX_EVAS_HH\n#define EFL_CXX_EVAS_HH\n" > $(top_builddir)/src/lib/evas/Evas.hh - @echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/evas/Evas.hh - @for i in $(evas_eolian_cxx_hh); do echo "#include " >> $(top_builddir)/src/lib/evas/Evas.hh; done - @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/evas/Evas.hh +lib/evas/Evas.eo.hh: $(evas_eolian_pub_files) $(_EOLIAN_CXX_DEP) + $(AM_V_EOLCXX) \ + $(MKDIR_P) $(dir $@); \ + $(EOLIAN_CXX) $(EOLIAN_FLAGS) -m -o $@ $(filter %.eo, $^) -CLEANFILES += $(evas_eolian_cxx_hh) $(evas_eolian_cxx_impl_hh) lib/evas/Evas.hh +CLEANFILES += $(evas_eolian_cxx_hh) $(evas_eolian_cxx_impl_hh) lib/evas/Evas.eo.hh ### Eldbus C++ installed_eldbuscxxmainheadersdir = $(includedir)/eldbus_cxx-@VMAJ@ -nodist_installed_eldbuscxxmainheaders_DATA = $(eldbus_eolian_cxx_hh) $(eldbus_eolian_cxx_impl_hh) lib/eldbus/Eldbus_Model.hh +nodist_installed_eldbuscxxmainheaders_DATA = $(eldbus_eolian_cxx_hh) $(eldbus_eolian_cxx_impl_hh) lib/eldbus/Eldbus_Model.eo.hh dist_installed_eldbuscxxmainheaders_DATA = \ bindings/cxx/eldbus_cxx/eldbus_basic.hh \ bindings/cxx/eldbus_cxx/eldbus_error.hh \ @@ -89,16 +72,15 @@ bindings/cxx/eldbus_cxx/eldbus_message.hh \ bindings/cxx/eldbus_cxx/eldbus_proxy_call.hh \ bindings/cxx/eldbus_cxx/eldbus_raw_tuple.hh \ bindings/cxx/eldbus_cxx/eldbus_service.hh \ -bindings/cxx/eldbus_cxx/eldbus_signature_traits.hh +bindings/cxx/eldbus_cxx/eldbus_signature_traits.hh \ +bindings/cxx/eldbus_cxx/Eldbus_Model.hh -lib/eldbus/Eldbus_Model.hh: $(eldbus_eolian_cxx_hh) - @echo @ECHO_E@ "#ifndef EFL_CXX_ELDBUS_MODEL_HH\n#define EFL_CXX_ELDBUS_MODEL_HH\n" > $(top_builddir)/src/lib/eldbus/Eldbus_Model.hh - @echo @ECHO_E@ "#include " >> $(top_builddir)/src/lib/eldbus/Eldbus_Model.hh - @echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/eldbus/Eldbus_Model.hh - @for i in $(eldbus_eolian_cxx_hh); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/eldbus/Eldbus_Model.hh; done - @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/eldbus/Eldbus_Model.hh +lib/eldbus/Eldbus_Model.eo.hh: $(eldbus_eolian_files) $(_EOLIAN_CXX_DEP) + $(AM_V_EOLCXX) \ + $(MKDIR_P) $(dir $@); \ + $(EOLIAN_CXX) $(EOLIAN_FLAGS) -m -o $@ $(filter %.eo, $^) -CLEANFILES += $(eldbus_eolian_cxx_hh) $(eldbus_eolian_cxx_impl_hh) lib/eldbus/Eldbus_Model.hh +CLEANFILES += $(eldbus_eolian_cxx_hh) $(eldbus_eolian_cxx_impl_hh) lib/eldbus/Eldbus_Model.eo.hh ### Eet C++ installed_eetcxxheadersdir = $(includedir)/eet-cxx-@VMAJ@ @@ -110,15 +92,15 @@ bindings/cxx/eet_cxx/Eet.hh ### Generated headers src/lib/edje installed_edjecxxmainheadersdir = $(includedir)/edje-cxx-@VMAJ@/ -nodist_installed_edjecxxmainheaders_DATA = $(edje_eolian_cxx_hh) $(edje_eolian_cxx_impl_hh) lib/edje/Edje.hh +dist_installed_edjecxxmainheaders_DATA = lib/edje/Edje.hh +nodist_installed_edjecxxmainheaders_DATA = $(edje_eolian_cxx_hh) $(edje_eolian_cxx_impl_hh) lib/edje/Edje.eo.hh -lib/edje/Edje.hh: $(edje_eolian_cxx_hh) - @echo @ECHO_E@ "#ifndef EFL_CXX_EDJE_HH\n#define EFL_CXX_EDJE_HH\n" > $(top_builddir)/src/lib/edje/Edje.hh - @echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/edje/Edje.hh - @for i in $(edje_eolian_cxx_hh); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/edje/Edje.hh; done - @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/edje/Edje.hh +lib/edje/Edje.eo.hh: $(edje_eolian_files) $(_EOLIAN_CXX_DEP) + $(AM_V_EOLCXX) \ + $(MKDIR_P) $(dir $@); \ + $(EOLIAN_CXX) $(EOLIAN_FLAGS) -m -o $@ $(filter %.eo, $^) -CLEANFILES += $(edje_eolian_cxx_hh) $(edje_eolian_cxx_impl_hh) lib/edje/Edje.hh +CLEANFILES += $(edje_eolian_cxx_hh) $(edje_eolian_cxx_impl_hh) lib/edje/Edje.eo.hh ### Ecore src/lib/ecore installed_ecorecxxheadersdir = $(includedir)/ecore-cxx-@VMAJ@ @@ -129,11 +111,10 @@ bindings/cxx/ecore_cxx/Ecore_Manual.hh nodist_installed_ecorecxxheaders_DATA = $(ecore_eolian_cxx_hh) $(ecore_eolian_cxx_impl_hh) \ lib/ecore/Ecore.eo.hh -lib/ecore/Ecore.eo.hh: $(ecore_eolian_cxx_hh) $(eo_eolian_cxx_hh) $(efl_eolian_cxx_hh) - @echo @ECHO_E@ "#ifndef EFL_CXX_ECORE_HH\n#define EFL_CXX_ECORE_HH\n" > $(top_builddir)/src/lib/ecore/Ecore.eo.hh - @echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh - @for i in $(ecore_eolian_cxx_hh); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh; done - @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/ecore/Ecore.eo.hh +lib/ecore/Ecore.eo.hh: $(ecore_eolian_files_public) $(_EOLIAN_CXX_DEP) + $(AM_V_EOLCXX) \ + $(MKDIR_P) $(dir $@); \ + $(EOLIAN_CXX) $(EOLIAN_FLAGS) -m -o $@ $(filter %.eo, $^) CLEANFILES += $(ecore_eolian_cxx_hh) $(ecore_eolian_cxx_impl_hh) lib/ecore/Ecore.eo.hh @@ -180,15 +161,15 @@ bindings/cxx/eina_cxx/Eina.hh ### Eio installed_eiocxxmainheadersdir = $(includedir)/eio-cxx-@VMAJ@/ -nodist_installed_eiocxxmainheaders_DATA = $(eio_eolian_cxx_hh) $(eio_eolian_cxx_impl_hh) lib/eio/Eio.hh +nodist_installed_eiocxxmainheaders_DATA = $(eio_eolian_cxx_hh) $(eio_eolian_cxx_impl_hh) lib/eio/Eio.eo.hh +dist_installed_eiocxxmainheaders_DATA = lib/eio/Eio.hh -lib/eio/Eio.hh: $(eio_eolian_cxx_hh) - @echo @ECHO_E@ "#ifndef EFL_CXX_EIO_HH\n#define EFL_CXX_EIO_HH\n" > $(top_builddir)/src/lib/eio/Eio.hh - @echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/eio/Eio.hh - @for i in $(eio_eolian_cxx_hh); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/eio/Eio.hh; done - @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/eio/Eio.hh +lib/eio/Eio.eo.hh: $(eio_eolian_files) $(_EOLIAN_CXX_DEP) + $(AM_V_EOLCXX) \ + $(MKDIR_P) $(dir $@); \ + $(EOLIAN_CXX) $(EOLIAN_FLAGS) -m -o $@ $(filter %.eo, $^) -CLEANFILES += $(eio_eolian_cxx_hh) $(eio_eolian_cxx_impl_hh) lib/eio/Eio.hh +CLEANFILES += $(eio_eolian_cxx_hh) $(eio_eolian_cxx_impl_hh) lib/eio/Eio.eo.hh ### Tests diff --git a/src/Makefile_Eolian_Cxx.am b/src/Makefile_Eolian_Cxx.am index 6d0ae1d73e..6abb3d6a40 100644 --- a/src/Makefile_Eolian_Cxx.am +++ b/src/Makefile_Eolian_Cxx.am @@ -145,8 +145,15 @@ tests/eolian_cxx/complex.eo.impl.hh \ tests/eolian_cxx/name1_name2_type_generation.eo.hh \ tests/eolian_cxx/name1_name2_type_generation.eo.impl.hh \ tests/eolian_cxx/name1_name2_type_generation.eo.h \ -tests/eolian_cxx/name1_name2_type_generation.eo.c - +tests/eolian_cxx/name1_name2_type_generation.eo.c \ +tests/eolian_cxx/cyclic1.eo.c \ +tests/eolian_cxx/cyclic1.eo.h \ +tests/eolian_cxx/cyclic1.eo.hh \ +tests/eolian_cxx/cyclic1.eo.impl.hh \ +tests/eolian_cxx/cyclic2.eo.c \ +tests/eolian_cxx/cyclic2.eo.h \ +tests/eolian_cxx/cyclic2.eo.hh \ +tests/eolian_cxx/cyclic2.eo.impl.hh tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \ -I$(top_builddir)/src/lib/efl \ @@ -181,7 +188,9 @@ tests/eolian_cxx/name_name.eo \ tests/eolian_cxx/ns_name.eo \ tests/eolian_cxx/ns_name_other.eo \ tests/eolian_cxx/name1_name2_type_generation.eo \ -tests/eolian_cxx/complex.eo +tests/eolian_cxx/complex.eo \ +tests/eolian_cxx/cyclic1.eo \ +tests/eolian_cxx/cyclic2.eo include Makefile_Eolian_Cxx_Helper.am diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc index 24a9dd62a1..18978a3fe9 100644 --- a/src/bin/eolian_cxx/eolian_cxx.cc +++ b/src/bin/eolian_cxx/eolian_cxx.cc @@ -32,8 +32,11 @@ namespace eolian_cxx { struct options_type { std::vector include_dirs; - std::string in_file; + std::vector in_files; std::string out_file; + bool main_header; + + options_type() : main_header(false) {} }; efl::eina::log_domain domain("eolian_cxx"); @@ -41,7 +44,7 @@ efl::eina::log_domain domain("eolian_cxx"); static bool opts_check(eolian_cxx::options_type const& opts) { - if (opts.in_file.empty()) + if (opts.in_files.empty()) { EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) << "Nothing to generate?" << std::endl; @@ -68,6 +71,7 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts) efl::eolian::grammar::attributes::klass_def klass_def(klass); std::vector klasses{klass_def}; + std::vector forward_klasses{klass_def}; std::set c_headers; std::set cpp_headers; @@ -82,6 +86,9 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts) assert(klass); c_headers.insert(eolian_class_file_get(klass) + std::string(".h")); cpp_headers.insert(eolian_class_file_get(klass) + std::string(".hh")); + efl::eolian::grammar::attributes::klass_def cls{klass}; + if(std::find(forward_klasses.begin(), forward_klasses.end(), cls) == forward_klasses.end()) + forward_klasses.push_back(cls); }; auto complex_function = [&] (efl::eolian::grammar::attributes::complex_type_def const& complex) @@ -112,6 +119,9 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts) Eolian_Class const* inherit = ::eolian_class_get_by_name(&*inherit_iterator); c_headers.insert(eolian_class_file_get(inherit) + std::string(".h")); cpp_headers.insert(eolian_class_file_get(inherit) + std::string(".hh")); + efl::eolian::grammar::attributes::klass_def klass{inherit}; + if(std::find(forward_klasses.begin(), forward_klasses.end(), klass) == forward_klasses.end()) + forward_klasses.push_back(klass); klass_function(inherit); } @@ -147,7 +157,7 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts) , std::vector& , std::vector& > attributes - {guard_name, c_headers, cpp_headers, klasses, klasses, klasses, klasses}; + {guard_name, c_headers, cpp_headers, klasses, forward_klasses, klasses, klasses}; if(opts.out_file == "-") { @@ -182,15 +192,11 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts) return false; } -#if 1 efl::eolian::grammar::class_header.generate (std::ostream_iterator(header_decl), attributes, efl::eolian::grammar::context_null()); efl::eolian::grammar::impl_header.generate (std::ostream_iterator(header_impl), klasses, efl::eolian::grammar::context_null()); -#else - efl::eolian::generate(header_decl, header_impl, cls, gen_opts); -#endif header_impl.close(); header_decl.close(); @@ -201,26 +207,75 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts) static void run(options_type const& opts) { - const Eolian_Class *klass = NULL; - char* dup = strdup(opts.in_file.c_str()); - char* base = basename(dup); - klass = ::eolian_class_get_by_file(base); - free(dup); - if (klass) + if(!opts.main_header) { - if (!generate(klass, opts)) - goto err; + const Eolian_Class *klass = NULL; + char* dup = strdup(opts.in_files[0].c_str()); + char* base = basename(dup); + klass = ::eolian_class_get_by_file(base); + free(dup); + if (klass) + { + if (!generate(klass, opts)) + { + EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) + << "Error generating: " << ::eolian_class_name_get(klass) + << std::endl; + assert(false && "error generating class"); + } + } + else + { + std::abort(); + } } else { - std::abort(); - } - return; - err: - EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) - << "Error generating: " << ::eolian_class_name_get(klass) - << std::endl; - assert(false && "error generating class"); + std::set headers; + std::set eo_files; + + for(auto&& name : opts.in_files) + { + bool b = ::eolian_file_parse(name.c_str()); + if(!b) + { + EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) + << "Failed parsing: " << name << "."; + } + char* dup = strdup(name.c_str()); + char* base = basename(dup); + Eolian_Class const* klass = ::eolian_class_get_by_file(base); + free(dup); + if (klass) + { + std::string filename = eolian_class_file_get(klass); + headers.insert(filename + std::string(".hh")); + eo_files.insert(filename); + } + } + + using efl::eolian::grammar::header_include_directive; + using efl::eolian::grammar::implementation_include_directive; + + auto main_header_grammar = + *header_include_directive // sequence + << *implementation_include_directive // sequence + ; + + std::tuple&, std::set&> attributes{headers, eo_files}; + + std::ofstream main_header; + main_header.open(opts.out_file); + if (!main_header.good()) + { + EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) + << "Can't open output file: " << opts.out_file << std::endl; + return; + } + + main_header_grammar.generate(std::ostream_iterator(main_header) + , attributes, efl::eolian::grammar::context_null()); + } } static void @@ -240,16 +295,16 @@ database_load(options_type const& opts) << "Eolian failed parsing eot files"; assert(false && "Error parsing eot files"); } - if (opts.in_file.empty()) + if (opts.in_files.empty()) { EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) << "No input file."; assert(false && "Error parsing input file"); } - if (!::eolian_file_parse(opts.in_file.c_str())) + if (!opts.main_header && !::eolian_file_parse(opts.in_files[0].c_str())) { EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) - << "Failed parsing: " << opts.in_file << "."; + << "Failed parsing: " << opts.in_files[0] << "."; assert(false && "Error parsing input file"); } if (!::eolian_database_validate()) @@ -307,13 +362,14 @@ opts_get(int argc, char **argv) const struct option long_options[] = { - { "in", required_argument, 0, 'I' }, - { "out-file", required_argument, 0, 'o' }, - { "version", no_argument, 0, 'v' }, - { "help", no_argument, 0, 'h' }, - { 0, 0, 0, 0 } + { "in", required_argument, 0, 'I' }, + { "out-file", required_argument, 0, 'o' }, + { "version", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, + { "main-header", no_argument, 0, 'm' }, + { 0, 0, 0, 0 } }; - const char* options = "I:D:o:c:arvh"; + const char* options = "I:D:o:c::marvh"; int c, idx; while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1) @@ -331,15 +387,20 @@ opts_get(int argc, char **argv) { _usage(argv[0]); } + else if(c == 'm') + { + opts.main_header = true; + } else if (c == 'v') { _print_version(); if (argc == 2) exit(EXIT_SUCCESS); } } - if (optind == argc-1) + if (optind != argc) { - opts.in_file = argv[optind]; + for(int i = optind; i != argc; ++i) + opts.in_files.push_back(argv[i]); } if (!eolian_cxx::opts_check(opts)) diff --git a/src/bindings/cxx/eldbus_cxx/Eldbus_Model.hh b/src/bindings/cxx/eldbus_cxx/Eldbus_Model.hh new file mode 100644 index 0000000000..f2aa9e1a2c --- /dev/null +++ b/src/bindings/cxx/eldbus_cxx/Eldbus_Model.hh @@ -0,0 +1,12 @@ +#ifndef EFL_CXX_ELDBUS_MODEL_HH +#define EFL_CXX_ELDBUS_MODEL_HH + +#include + +#ifdef EFL_BETA_API_SUPPORT + +#include + +#endif +#endif + diff --git a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh index 524863e418..7a2f8fb765 100644 --- a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh +++ b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh @@ -279,11 +279,11 @@ T convert_to_c(V&& object); namespace impl { -template +template auto convert_to_c_impl -(T&& v, tag, typename std::enable_if::type, U>::value>::type* =0) -> decltype(std::forward(v)) +(V&& v, tag, typename std::enable_if::type, U>::value>::type* =0) -> decltype(std::forward(v)) { - return std::forward(v); + return std::forward(v); } template diff --git a/src/examples/elementary/button_cxx_example_00.cc b/src/examples/elementary/button_cxx_example_00.cc index 99901d2aa2..9239f74734 100644 --- a/src/examples/elementary/button_cxx_example_00.cc +++ b/src/examples/elementary/button_cxx_example_00.cc @@ -24,7 +24,7 @@ elm_main (int argc, char *argv[]) win.autohide_set(true); ::elm::Button btn(win); - btn.eo_cxx::efl::Text::text_set("Good-Bye, World!"); + btn.eo_cxx::elm::Layout::text_set(nullptr,"Good-Bye, World!"); btn.eo_cxx::efl::Gfx::size_set(120, 30); btn.eo_cxx::efl::Gfx::position_set(60, 15); btn.visible_set(true); diff --git a/src/examples/elementary/calendar_cxx_example_02.cc b/src/examples/elementary/calendar_cxx_example_02.cc index 7061e57c4a..02a1edea3e 100644 --- a/src/examples/elementary/calendar_cxx_example_02.cc +++ b/src/examples/elementary/calendar_cxx_example_02.cc @@ -3,6 +3,7 @@ #include "elementary_config.h" #endif +#include #include static char * diff --git a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc index 2fedf12748..5cd6b20596 100644 --- a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc +++ b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc @@ -8,6 +8,8 @@ #include "ns_colourable.eo.hh" #include "ns_colourablesquare.eo.hh" +#include "ns_colourable.eo.impl.hh" +#include "ns_colourablesquare.eo.impl.hh" #include diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc index eb093d904b..028a429039 100644 --- a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc +++ b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc @@ -9,6 +9,8 @@ #include "ns_colourable.eo.hh" #include "ns_colourablesquare.eo.hh" +#include "ns_colourable.eo.impl.hh" +#include "ns_colourablesquare.eo.impl.hh" int main() diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc b/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc index 11209783bc..2ca0e975de 100644 --- a/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc +++ b/src/examples/eolian_cxx/eolian_cxx_simple_01_cxx_impl.cc @@ -9,6 +9,8 @@ #include "colourable.eo.hh" #include "colourablesquare.eo.hh" +#include "ns_colourable.eo.impl.hh" +#include "ns_colourablesquare.eo.impl.hh" int main() diff --git a/src/lib/.gitignore b/src/lib/.gitignore index 190a85e1d6..aaec4c069e 100644 --- a/src/lib/.gitignore +++ b/src/lib/.gitignore @@ -1,11 +1,12 @@ /ecore_x/ecore_x_version.h /efl/Efl_Config.h -/efl/Efl.hh /eina/eina_config.h -/ecore_audio/Ecore_Audio.hh /ecore/Ecore.eo.hh -/evas/Evas.hh -/edje/Edje.hh /edje/Edje.eo.hh -/eio/Eio.hh -/eldbus/Eldbus_Model.hh +/eio/Eio.eo.hh +/elementary/Elementary.eo.hh +/evas/Evas.eo.hh +/efl/Efl.eo.hh +/eldbus/Eldbus_Model.eo.hh + + diff --git a/src/lib/edje/Edje.hh b/src/lib/edje/Edje.hh new file mode 100644 index 0000000000..4550181ac8 --- /dev/null +++ b/src/lib/edje/Edje.hh @@ -0,0 +1,9 @@ +#ifndef EFL_CXX_EDJE_HH +#define EFL_CXX_EDJE_HH + +#ifdef EFL_BETA_API_SUPPORT + +#include + +#endif +#endif diff --git a/src/lib/efl/.gitignore b/src/lib/efl/.gitignore index 3732c0ce33..e69de29bb2 100644 --- a/src/lib/efl/.gitignore +++ b/src/lib/efl/.gitignore @@ -1 +0,0 @@ -Efl.hh diff --git a/src/lib/efl/Efl.hh b/src/lib/efl/Efl.hh new file mode 100644 index 0000000000..20dfc1a90d --- /dev/null +++ b/src/lib/efl/Efl.hh @@ -0,0 +1,11 @@ +#ifndef EFL_EFL_HH +#define EFL_EFL_HH + +#ifdef EFL_BETA_API_SUPPORT + +#include + +#endif +#endif + + diff --git a/src/lib/eio/Eio.hh b/src/lib/eio/Eio.hh new file mode 100644 index 0000000000..78c0f391d8 --- /dev/null +++ b/src/lib/eio/Eio.hh @@ -0,0 +1,9 @@ +#ifndef EFL_CXX_EIO_HH +#define EFL_CXX_EIO_HH +#ifdef EFL_BETA_API_SUPPORT + +#include "Eio.eo.hh" + +#endif +#endif + diff --git a/src/lib/elementary/.gitignore b/src/lib/elementary/.gitignore index 089c32dd72..9076648525 100644 --- a/src/lib/elementary/.gitignore +++ b/src/lib/elementary/.gitignore @@ -1,4 +1,3 @@ -/Elementary.hh /Elementary_Options.h /elm_intro.h /*.eo.c diff --git a/src/lib/elementary/Elementary.hh b/src/lib/elementary/Elementary.hh new file mode 100644 index 0000000000..215632bb10 --- /dev/null +++ b/src/lib/elementary/Elementary.hh @@ -0,0 +1,26 @@ +#ifndef EFL_CXX_ELEMENTARY_HH +#define EFL_CXX_ELEMENTARY_HH +#if defined(ELEMENTARY_H) || defined(ELM_WIDGET_H) +#error "Do not include Elm C API headers before including Elementary.hh" +#endif + +#ifndef EFL_BETA_API_SUPPORT +#define EFL_BETA_API_SUPPORT +#endif +#ifndef EFL_EO_API_SUPPORT +#define EFL_EO_API_SUPPORT +#endif +#ifndef ELM_INTERNAL_API_ARGESFSDFEFC +#define ELM_INTERNAL_API_ARGESFSDFEFC +#endif + +#include + +extern "C" { +#include "Elementary.h" +#include "elm_widget.h" +} + +#include "Elementary.eo.hh" + +#endif diff --git a/src/lib/eolian_cxx/grammar/class_declaration.hpp b/src/lib/eolian_cxx/grammar/class_declaration.hpp index 6f23641e4d..bed1a5696f 100644 --- a/src/lib/eolian_cxx/grammar/class_declaration.hpp +++ b/src/lib/eolian_cxx/grammar/class_declaration.hpp @@ -15,6 +15,8 @@ namespace efl { namespace eolian { namespace grammar { struct class_declaration_generator { + bool type_traits; + template bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const { @@ -30,11 +32,12 @@ struct class_declaration_generator auto close_namespace = *(lit("} ")) << "\n"; if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false; - if(!as_generator - ( - "namespace efl { namespace eo { template<> struct is_eolian_object< " - "::" << *(lower_case[string] << "::") << string << "> : ::std::true_type {}; } }\n" - ).generate(sink, std::make_tuple(cpp_namespaces, cls.cxx_name), context)) return false; + if(type_traits) + if(!as_generator + ( + "namespace efl { namespace eo { template<> struct is_eolian_object< " + "::" << *(lower_case[string] << "::") << string << "> : ::std::true_type {}; } }\n" + ).generate(sink, std::make_tuple(cpp_namespaces, cls.cxx_name), context)) return false; return true; @@ -49,7 +52,8 @@ template <> struct attributes_needed : std::integral_constant {}; } -class_declaration_generator const class_declaration = {}; +class_declaration_generator const class_declaration = {true}; +class_declaration_generator const class_forward_declaration = {false}; } } } diff --git a/src/lib/eolian_cxx/grammar/header.hpp b/src/lib/eolian_cxx/grammar/header.hpp index 96e123593c..63a6095949 100644 --- a/src/lib/eolian_cxx/grammar/header.hpp +++ b/src/lib/eolian_cxx/grammar/header.hpp @@ -25,11 +25,12 @@ auto class_header = "#include \n" << *header_include_directive // sequence << *class_declaration // sequence | class + << *class_forward_declaration // sequence | class << "\nnamespace eo_cxx {\n" << *base_class_definition // sequence | class << "}\n" << *class_definition // sequence | class - << *implementation_include_directive + // << *implementation_include_directive ] ; diff --git a/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp index dab1e0a7e9..6c2631ab80 100644 --- a/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp +++ b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp @@ -22,6 +22,12 @@ struct implementation_include_directive_generator return as_generator("#include \"" << string << ".impl.hh\"\n") .generate(sink, std::string(eolian_class_file_get(get_klass(get_klass_name(cls)))), add_lower_case_context(ctx)); } + template + bool generate(OutputIterator sink, std::string const& cls, Context const& ctx) const + { + return as_generator("#include \"" << string << ".impl.hh\"\n") + .generate(sink, cls, add_lower_case_context(ctx)); + } }; template <> diff --git a/src/lib/eolian_cxx/grammar/keyword.hpp b/src/lib/eolian_cxx/grammar/keyword.hpp index 9359892f9c..b64201eac3 100644 --- a/src/lib/eolian_cxx/grammar/keyword.hpp +++ b/src/lib/eolian_cxx/grammar/keyword.hpp @@ -5,7 +5,7 @@ namespace efl { namespace eolian { namespace grammar { inline std::string escape_keyword(std::string const& name) { - if(name == "delete" || name == "register") + if(name == "delete" || name == "register" || name == "do") return "cxx_" + name; return name; } diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp index 4b9bc48205..c663f289b8 100644 --- a/src/lib/eolian_cxx/grammar/klass_def.hpp +++ b/src/lib/eolian_cxx/grammar/klass_def.hpp @@ -315,6 +315,18 @@ struct parameter_def std::string param_name; std::string c_type; + friend inline bool operator==(parameter_def const& lhs, parameter_def const& rhs) + { + return lhs.direction == rhs.direction + && lhs.type == rhs.type + && lhs.param_name == rhs.param_name + && lhs.c_type == rhs.c_type; + } + friend inline bool operator!=(parameter_def const& lhs, parameter_def const& rhs) + { + return !(lhs == rhs); + } + parameter_def(parameter_direction direction, type_def type, std::string param_name, std::string c_type) : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), c_type(std::move(c_type)) {} parameter_def(Eolian_Function_Parameter const* param) @@ -384,6 +396,20 @@ struct function_def bool is_beta; bool is_protected; + friend inline bool operator==(function_def const& lhs, function_def const& rhs) + { + return lhs.return_type == rhs.return_type + && lhs.name == rhs.name + && lhs.parameters == rhs.parameters + && lhs.c_name == rhs.c_name + && lhs.is_beta == rhs.is_beta + && lhs.is_protected == rhs.is_protected; + } + friend inline bool operator!=(function_def const& lhs, function_def const& rhs) + { + return !(lhs == rhs); + } + function_def(type_def return_type, std::string name, std::vector parameters , std::string c_name, bool is_beta) : return_type(return_type), name(name), parameters(parameters), c_name(c_name), is_beta(is_beta) {} @@ -504,6 +530,19 @@ struct event_def std::string name, c_name; bool beta, protect; + friend inline bool operator==(event_def const& lhs, event_def const& rhs) + { + return lhs.type == rhs.type + && lhs.name == rhs.name + && lhs.c_name == rhs.c_name + && lhs.beta == rhs.beta + && lhs.protect == rhs.protect; + } + friend inline bool operator!=(event_def const& lhs, event_def const& rhs) + { + return !(lhs == rhs); + } + event_def(type_def type, std::string name, std::string c_name, bool beta, bool protect) : type(type), name(name), c_name(c_name), beta(beta), protect(protect) {} event_def(Eolian_Event const* event) @@ -558,6 +597,21 @@ struct klass_def class_type type; std::vector events; + friend inline bool operator==(klass_def const& lhs, klass_def const& rhs) + { + return lhs.eolian_name == rhs.eolian_name + && lhs.cxx_name == rhs.cxx_name + && lhs.namespaces == rhs.namespaces + && lhs.functions == rhs.functions + && lhs.inherits == rhs.inherits + && lhs.type == rhs.type + && lhs.events == rhs.events; + } + friend inline bool operator!=(klass_def const& lhs, klass_def const& rhs) + { + return !(lhs == rhs); + } + klass_def(std::string eolian_name, std::string cxx_name , std::vector namespaces , std::vector functions diff --git a/src/lib/evas/Evas.hh b/src/lib/evas/Evas.hh new file mode 100644 index 0000000000..4bef41958f --- /dev/null +++ b/src/lib/evas/Evas.hh @@ -0,0 +1,9 @@ +#ifndef EFL_EVAS_HH +#define EFL_EVAS_HH +#ifdef EFL_BETA_API_SUPPORT + +#include "Evas.eo.hh" + +#endif +#endif + diff --git a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc index c9ee5c8e9b..0e46e84ff6 100644 --- a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc +++ b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc @@ -5,7 +5,9 @@ #include #include +#include #include +#include #include "eolian_cxx_suite.h" diff --git a/src/tests/eolian_cxx/eolian_cxx_test_cyclic.cc b/src/tests/eolian_cxx/eolian_cxx_test_cyclic.cc index f338133c45..dcd88ac151 100644 --- a/src/tests/eolian_cxx/eolian_cxx_test_cyclic.cc +++ b/src/tests/eolian_cxx/eolian_cxx_test_cyclic.cc @@ -4,6 +4,13 @@ #include +extern "C" { +typedef Eo Cyclic1; +typedef Eo Cyclic2; +} + +#include +#include #include #include