*.eo.h
*.eo.legacy.h
*.eo.hh
+*.eo.impl.hh
*.eo.lua
*.luac
.dir-locals.el
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
-EXCLUDE_SYMBOLS =
+EXCLUDE_SYMBOLS = eo_cxx::*
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
EAPI= \
EINA_PURE= \
EINA_CONST= \
- EINA_UNUSED=
+ EINA_UNUSED= \
+ EFL_DOXYGEN=1 \
+ "EO_CXX_INHERIT(name)=::name"
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
generated_ecore_audio_cxx_all = \
$(generated_ecore_audio_cxx_bindings) \
+ lib/ecore_audio/ecore_audio.eo.impl.hh \
+ lib/ecore_audio/ecore_audio_in.eo.impl.hh \
+ lib/ecore_audio/ecore_audio_out.eo.impl.hh \
+ lib/ecore_audio/ecore_audio_in_sndfile.eo.impl.hh \
+ lib/ecore_audio/ecore_audio_out_sndfile.eo.impl.hh \
+ lib/ecore_audio/ecore_audio_out_pulse.eo.impl.hh \
+ lib/ecore_audio/ecore_audio_in_tone.eo.impl.hh \
lib/ecore_audio/Ecore_Audio.hh
CLEANFILES += $(generated_ecore_audio_cxx_all)
generated_ecore_cxx_all = \
$(generated_ecore_cxx_bindings) \
+ lib/ecore/ecore_poller.eo.impl.hh \
+ lib/ecore/ecore_job.eo.impl.hh \
+ lib/ecore/ecore_idler.eo.impl.hh \
+ lib/ecore/ecore_idle_exiter.eo.impl.hh \
+ lib/ecore/ecore_animator.eo.impl.hh \
+ lib/ecore/ecore_parent.eo.impl.hh \
lib/ecore/Ecore.eo.hh
CLEANFILES += $(generated_ecore_cxx_all)
generated_edje_cxx_all = \
$(generated_edje_cxx_bindings) \
+ lib/edje/edje_object.eo.impl.hh \
+ lib/edje/edje_edit.eo.impl.hh \
lib/edje/Edje.hh
CLEANFILES += $(generated_edje_cxx_all)
generated_efl_cxx_all = \
$(generated_efl_cxx_bindings) \
+ lib/efl/interfaces/efl_control.eo.impl.hh \
+ lib/efl/interfaces/efl_file.eo.impl.hh \
+ lib/efl/interfaces/efl_image.eo.impl.hh \
+ lib/efl/interfaces/efl_player.eo.impl.hh \
+ lib/efl/interfaces/efl_text.eo.impl.hh \
+ lib/efl/interfaces/efl_text_properties.eo.impl.hh \
lib/efl/Efl.hh
CLEANFILES += $(generated_efl_cxx_all)
generated_eo_cxx_bindings = \
lib/eo/eo_base.eo.hh \
-lib/eo/eo_abstract_class.eo.hh
+lib/eo/eo_base.eo.impl.hh \
+lib/eo/eo_abstract_class.eo.hh \
+lib/eo/eo_abstract_class.eo.impl.hh
### Library
installed_eoliancxxgrammarheadersdir = $(includedir)/eolian-cxx-@VMAJ@/grammar/
dist_installed_eoliancxxgrammarheaders_DATA = \
lib/eolian_cxx/grammar/comment.hh \
+lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh \
lib/eolian_cxx/grammar/eo_class_constructors_generator.hh \
lib/eolian_cxx/grammar/eo_class_events_generator.hh \
lib/eolian_cxx/grammar/eo_class_functions_generator.hh \
tests/eolian_cxx/simple.eo.c \
tests/eolian_cxx/simple.eo.h \
tests/eolian_cxx/simple.eo.hh \
-tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h \
-tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h \
-tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h \
-tests/eolian_cxx/d.eo.hh tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h
+tests/eolian_cxx/simple.eo.impl.hh \
+tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.impl.hh tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h \
+tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.impl.hh tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h \
+tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.impl.hh tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h \
+tests/eolian_cxx/d.eo.hh tests/eolian_cxx/d.eo.impl.hh tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h
tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \
-I$(top_builddir)/src/lib/efl \
%.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -o $@ $<
+%.eo.impl.hh: %.eo.hh $(_EOLIAN_CXX_DEP)
+ true $<
+
CLEANFILES += $(BUILT_SOURCES)
@for i in $(generated_evas_canvas_cxx_bindings); do echo "#include <canvas/$$(basename $$i)>" >> $(top_builddir)/src/lib/evas/Evas.hh; done
@echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/evas/Evas.hh
-CLEANFILES += \
+generated_evas_canvas_cxx_all = \
$(generated_evas_canvas_cxx_bindings) \
+lib/evas/canvas/evas_line.eo.impl.hh \
+lib/evas/canvas/evas_polygon.eo.impl.hh \
+lib/evas/canvas/evas_rectangle.eo.impl.hh \
+lib/evas/canvas/evas_text.eo.impl.hh \
+lib/evas/canvas/evas_textblock.eo.impl.hh \
+lib/evas/canvas/evas_textgrid.eo.impl.hh \
+lib/evas/canvas/evas_signal_interface.eo.impl.hh \
+lib/evas/canvas/evas_object_smart.eo.impl.hh \
+lib/evas/canvas/evas_smart_clipped.eo.impl.hh \
+lib/evas/canvas/evas_table.eo.impl.hh \
+lib/evas/canvas/evas_common_interface.eo.impl.hh \
+lib/evas/canvas/evas_object.eo.impl.hh \
+lib/evas/canvas/evas_canvas.eo.impl.hh \
+lib/evas/canvas/evas_grid.eo.impl.hh \
+lib/evas/canvas/evas_image.eo.impl.hh \
+lib/evas/canvas/evas_out.eo.impl.hh \
+lib/evas/canvas/evas_draggable_interface.eo.impl.hh \
+lib/evas/canvas/evas_clickable_interface.eo.impl.hh \
+lib/evas/canvas/evas_scrollable_interface.eo.impl.hh \
+lib/evas/canvas/evas_selectable_interface.eo.impl.hh \
+lib/evas/canvas/evas_zoomable_interface.eo.impl.hh \
+lib/evas/canvas/evas_box.eo.impl.hh \
+lib/evas/canvas/evas_3d_camera.eo.impl.hh \
+lib/evas/canvas/evas_3d_light.eo.impl.hh \
+lib/evas/canvas/evas_3d_material.eo.impl.hh \
+lib/evas/canvas/evas_3d_mesh.eo.impl.hh \
+lib/evas/canvas/evas_3d_node.eo.impl.hh \
+lib/evas/canvas/evas_3d_object.eo.impl.hh \
+lib/evas/canvas/evas_3d_scene.eo.impl.hh \
+lib/evas/canvas/evas_3d_texture.eo.impl.hh \
lib/evas/Evas.hh
+CLEANFILES += \
+$(generated_evas_canvas_cxx_all)
+
installed_evascxxmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/
nodist_installed_evascxxmainheaders_DATA = lib/evas/Evas.hh
installed_evascxxcanvasheadersdir = $(includedir)/evas-cxx-@VMAJ@/canvas
-nodist_installed_evascxxcanvasheaders_DATA = $(generated_evas_canvas_cxx_bindings)
+nodist_installed_evascxxcanvasheaders_DATA = $(generated_evas_canvas_cxx_all)
### Unit tests
efl::eolian::eo_function set_ =
{
efl::eolian::eo_function::regular_,
+ function_scope(prop_),
function_name(prop_) + "_set",
function_impl(prop_) + "_set",
function_return_type(prop_, eolian_cxx::setter),
efl::eolian::eo_function get_ =
{
efl::eolian::eo_function::regular_,
+ function_scope(prop_),
function_name(prop_) + "_get",
function_impl(prop_) + "_get",
function_return_type(prop_, eolian_cxx::getter),
{
cls.functions.push_back({
function_type(func),
+ function_scope(func),
function_name(func),
function_impl(func),
function_return_type(func),
{
efl::eolian::eo_class cls = eolian_cxx::convert_eolian_class(klass);
efl::eolian::eo_generator_options gen_opts = generator_options(klass);
- std::string outname = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file;
+ std::string header_decl_file_name = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file;
+
+ std::string header_impl_file_name = header_decl_file_name;
+ std::size_t dot_pos = header_impl_file_name.rfind(".hh");
+ if (dot_pos != std::string::npos)
+ header_impl_file_name.insert(dot_pos, ".impl");
+ else
+ header_impl_file_name.insert(header_impl_file_name.size(), ".impl");
+
+ std::size_t slash_pos = header_decl_file_name.rfind('/');
+ gen_opts.header_decl_file_name = (slash_pos == std::string::npos) ?
+ header_decl_file_name :
+ header_decl_file_name.substr(slash_pos+1);
+
+ slash_pos = header_impl_file_name.rfind('/');
+ gen_opts.header_impl_file_name = (slash_pos == std::string::npos) ?
+ header_impl_file_name :
+ header_impl_file_name.substr(slash_pos+1);
+
if (!opts.out_dir.empty())
{
- outname = opts.out_dir + "/" + outname;
+ header_decl_file_name = opts.out_dir + "/" + header_decl_file_name;
+ header_impl_file_name = opts.out_dir + "/" + header_impl_file_name;
}
if(opts.out_file == "-")
{
- efl::eolian::generate(std::cout, cls, gen_opts);
+ efl::eolian::generate(std::cout, std::cout, cls, gen_opts);
}
else
{
- std::ofstream outfile;
- outfile.open(outname);
- if (outfile.good())
+ std::ofstream header_decl;
+ header_decl.open(header_decl_file_name);
+ if (!header_decl.good())
{
- efl::eolian::generate(outfile, cls, gen_opts);
- outfile.close();
+ EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
+ << "Can't open output file: " << header_decl_file_name << std::endl;
+ return false;
}
- else
+
+ std::ofstream header_impl;
+ header_impl.open(header_impl_file_name);
+ if (!header_impl.good())
{
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
- << "Can't open output file: " << outname << std::endl;
+ << "Can't open output file: " << header_impl_file_name << std::endl;
return false;
}
+
+ efl::eolian::generate(header_decl, header_impl, cls, gen_opts);
+
+ header_decl.close();
+ header_impl.close();
}
return true;
}
struct method_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_METHOD; };
method_t const method = {};
+inline efl::eolian::eolian_scope
+eolian_scope_cxx(Eolian_Object_Scope s)
+{
+ using efl::eolian::eolian_scope;
+ return s == EOLIAN_SCOPE_PRIVATE ? eolian_scope::private_ :
+ s == EOLIAN_SCOPE_PROTECTED ? eolian_scope::protected_ :
+ eolian_scope::public_;
+}
+
inline const Eolian_Class*
class_from_file(std::string const& file)
{
return ::eolian_function_is_constructor(&func, &cls);
}
+inline efl::eolian::eolian_scope
+function_scope(Eolian_Function const& func)
+{
+ return eolian_scope_cxx(::eolian_function_scope_get(&func));
+}
+
inline bool
function_is_visible(Eolian_Function const& func, Eolian_Function_Type func_type)
{
- return (::eolian_function_scope_get(&func) == EOLIAN_SCOPE_PUBLIC &&
- ! ::eolian_function_is_legacy_only(&func, func_type));
+ Eolian_Object_Scope s = ::eolian_function_scope_get(&func);
+ return ((s == EOLIAN_SCOPE_PUBLIC || s == EOLIAN_SCOPE_PROTECTED) &&
+ !::eolian_function_is_legacy_only(&func, func_type));
}
inline bool
std::string name_ = safe_str(name);
std::transform(name_.begin(), name_.end(), name_.begin(),
[](int c) { return c != ',' ? c : '_'; });
+ event.scope = eolian_scope_cxx(::eolian_event_scope_get(event_));
event.name = normalize_spaces(name_);
event.eo_name = safe_upper
(find_replace(class_full_name(klass), ".", "_") + "_EVENT_" + event.name);
{"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}},
{"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}},
{"Edje_Signal_Cb", eolian_type::callback_, {"Edje.h"}},
- {"Eina_Accessor *", eolian_type::complex_, false, false, true, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
- {"Eina_Bool", eolian_type::simple_, false, false, false, "bool", {}},
- {"Eina_Bool *", eolian_type::simple_, false, false, false, "bool*", {}},
- {"Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
- {"Eina_Inlist *", eolian_type::complex_, false, true, true, "::efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
- {"Eina_Iterator *", eolian_type::complex_, false, false, true, "::efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
- {"Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
- {"Eina_List *", eolian_type::complex_, false, true, true, "::efl::eina::list", {"eina-cxx/eina_list.hh"}},
- {"const Eina_List *", eolian_type::complex_, true, false, true, "::efl::eina::crange_list", {"eina-cxx/eina_list.hh"}},
+ {"Eina_Accessor *", eolian_type::complex_, false, false, true, false, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
+ {"Eina_Bool", eolian_type::simple_, false, false, false, false, "bool", {}},
+ {"Eina_Bool *", eolian_type::simple_, false, false, false, false, "bool*", {}},
+ {"Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
+ {"Eina_Inlist *", eolian_type::complex_, false, true, true, true, "::efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
+ {"Eina_Iterator *", eolian_type::complex_, false, false, true, true, "::efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
+ {"Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
+ {"Eina_List *", eolian_type::complex_, false, true, true, true, "::efl::eina::list", {"eina-cxx/eina_list.hh"}},
+ {"const Eina_List *", eolian_type::complex_, true, false, true, true, "::efl::eina::crange_list", {"eina-cxx/eina_list.hh"}},
{"Eio_Filter_Direct_Cb", eolian_type::callback_, {"Eio.h"}},
- {"Emodel *", eolian_type::simple_, false, false, true, "::emodel", {"Emodel.hh"}},
- {"Eo *", eolian_type::simple_, false, true, true, "::efl::eo::concrete", {"eo_concrete.hh"}},
- {"Eo *", eolian_type::simple_, false, false, true, "::efl::eo::concrete", {"eo_concrete.hh"}},
+ {"Emodel *", eolian_type::simple_, false, false, true, false, "::emodel", {"Emodel.hh"}},
+ {"Eo *", eolian_type::simple_, false, true, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
+ {"Eo *", eolian_type::simple_, false, false, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
//{"Evas_Object_Box_Layout", eolian_type::callback_, {"Evas.h"}},
- {"Evas_Object *", eolian_type::simple_, false, false, true, "::evas::object", {"canvas/evas_object.eo.hh"}},
- {"char *", eolian_type::simple_, false, true, true, "std::unique_ptr<char*>", {"memory"}},
- {"const Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
- {"const Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
- {"const char *", eolian_type::simple_, false, false, true, "std::string", {"string"}},
+ {"Evas_Object *", eolian_type::simple_, false, false, true, false, "::evas::object", {"canvas/evas_object.eo.hh"}},
+ {"char *", eolian_type::simple_, false, true, true, false, "std::unique_ptr<char*>", {"memory"}},
+ {"const Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
+ {"const Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
+ {"const char *", eolian_type::simple_, false, false, true, true, "::efl::eina::string_view", {"string"}},
};
}
#endif
#endif
+#if !defined(EFL_DOXYGEN) && !defined(EO_CXX_INHERIT)
+# define EO_CXX_INHERIT(name) ::eo_cxx::name
+#elif !defined(EO_CXX_INHERIT)
+# define EO_CXX_INHERIT(name) ::name
+#endif
+
namespace efl { namespace eo {
/// @addtogroup Efl_Cxx_API
#include <string>
#include <tuple>
+#include <utility>
#include <type_traits>
#include <Eina.hh>
return x->c_str();
}
+inline const char*
+to_c(eina::string_view const& x)
+{
+ return x.data();
+}
+
+inline const char*
+to_c(eina::optional<eina::string_view> const& x)
+{
+ if (!x)
+ return nullptr;
+ return x->data();
+}
+
inline const char*
to_c(efl::eina::stringshare const& x)
{
return std::string(x);
}
+inline eina::string_view
+to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::string_view>)
+{
+ return eina::string_view(x);
+}
+
+inline eina::optional<eina::string_view>
+to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<eina::string_view> >)
+{
+ if (!x)
+ return nullptr;
+ return eina::string_view(x);
+}
+
template <typename T, typename Enable = void>
struct traits
{
typedef const char* type;
};
+template <typename T>
+struct traits
+ <T, typename std::enable_if<std::is_base_of<::efl::eina::basic_string_view<char>, T>::value>::type>
+{
+ typedef const char* type;
+};
+
template <typename T, typename ...Args>
inline efl::eina::range_list<T const>
to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_list<T> >)
return EO_CALLBACK_CONTINUE;
}
+template <typename F>
+inline
+std::vector<F>& get_static_callback_vector()
+{
+ static std::vector<F> vec;
+ return vec;
+}
+
+template <typename F>
+inline
+F* alloc_static_callback(F&& f)
+{
+ get_static_callback_vector<F>().push_back(std::forward<F>(f));
+ return &(get_static_callback_vector<F>().back());
+}
+
} } // namespace efl { namespace eolian {
#endif // EFL_EOLIAN_INTEROP_HH
colourable.eo.c \
colourable.eo.h \
colourable.eo.hh \
+ colourable.eo.impl.hh \
colourablesquare.eo.c \
colourablesquare.eo.h \
- colourablesquare.eo.hh
+ colourablesquare.eo.hh \
+ colourablesquare.eo.impl.hh
BUILT_SOURCES = $(GENERATED)
CLEANFILES += $(BUILT_SOURCES)
%.eo.hh: %.eo
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I${abs_srcdir} -o $@ $<
+%.eo.impl.hh: %.eo.hh
+ true $<
+
%.eo.c: %.eo
$(AM_V_EOL)$(EOLIAN_GEN) --eo --legacy $(EOLIAN_FLAGS) --gc -o $@ $<
namespace efl { namespace eolian {
inline void
-generate(std::ostream& out, eo_class const& cls, eo_generator_options const& opts)
+generate(std::ostream& header_decl,
+ std::ostream& header_impl,
+ eo_class const& cls,
+ eo_generator_options const& opts)
{
- grammar::eo_header_generator(out, cls, opts);
+ grammar::eo_headers_generator(header_decl, header_impl, cls, opts);
}
} }
typedef std::vector<eo_parameter> parameters_container_type;
typedef std::vector<eo_event> events_container_type;
+
+enum class eolian_scope
+ {
+ public_, protected_, private_
+ };
+
struct eolian_type
{
enum category_type
, is_const(false)
, is_own(false)
, is_class(false)
+ , binding_requires_optional(false)
, binding()
, includes()
{}
bool is_const_,
bool is_own_,
bool is_class_,
+ bool binding_requires_optional_,
std::string binding_,
includes_container_type includes_)
: native(native_)
, is_const(is_const_)
, is_own(is_own_)
, is_class(is_class_)
+ , binding_requires_optional(binding_requires_optional_)
, binding(binding_)
, includes(includes_)
{
eolian_type(std::string native_,
category_type category_,
includes_container_type const& includes_)
- : eolian_type(native_, category_, false, false, false, "", includes_)
+ : eolian_type(native_, category_, false, false, false, false, "", includes_)
{
assert(category == callback_);
}
bool is_const;
bool is_own;
bool is_class;
+ bool binding_requires_optional;
std::string binding;
includes_container_type includes;
};
};
const efl::eolian::eolian_type
-void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, "", {} };
+void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, false, "", {} };
inline bool
type_is_void(eolian_type_instance const& type)
return type_is_class(type.front());
}
+inline bool
+type_binding_requires_optional(eolian_type const& type)
+{
+ return type.binding_requires_optional;
+}
+
+inline bool
+type_binding_requires_optional(eolian_type_instance const& type)
+{
+ assert(!type.empty());
+ return type_binding_requires_optional(type.front());
+}
+
inline bool
type_is_nonull(eolian_type_instance const& type)
{
struct eo_generator_options
{
+ std::string header_decl_file_name;
+ std::string header_impl_file_name;
includes_container_type cxx_headers;
includes_container_type c_headers;
};
regular_, class_
};
eo_function_type type;
+ eolian_scope scope;
std::string name;
std::string impl;
eolian_type_instance ret;
struct eo_event
{
+ eolian_scope scope;
std::string name;
std::string eo_name;
//parameters_container_type params; // XXX desirable.
{
std::string _doc;
int _tab;
- comment(std::string const& doc, int tab = 0)
- : _doc(doc), _tab(tab)
+ std::string _if_empty;
+ comment(std::string const& doc, int tab = 0, std::string const& if_empty = "")
+ : _doc(doc), _tab(tab), _if_empty(if_empty)
{}
};
inline std::ostream&
operator<<(std::ostream& out, comment const& x)
{
- std::istringstream ss(x._doc);
+ std::string const& doc = !x._doc.empty() ? x._doc : x._if_empty;
+ std::istringstream ss(doc);
std::string line;
while(std::getline(ss, line))
{
last = cls.ancestors.cend();
for (it = first; it != last; ++it)
{
- out << tab(2) << ", ::" << abstract_namespace << "::" << *it << endl;
+ out << tab(2) << ", EO_CXX_INHERIT(" << *it << ")" << endl;
}
return out;
}
{
eo_constructor const& c = *it;
+ // Hide documentation condition
+ out << comment("@cond LOCAL", 1);
+
// Struct declaration
out << template_parameters_declaration(c.params, 1)
<< tab(1) << "struct " << constructor_functor_type_name(c) << endl
);
// Close struct
- out << tab(1) << "};" << endl << endl;
+ out << tab(1) << "};" << endl;
+
+ // End documentation condition
+ out << comment("@endcond", 1) << endl;
}
return out;
continue;
}
- out << comment(c.comment, 0)
+ out << comment(c.comment, 1)
<< template_parameters_declaration(c.params, 1)
<< tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
<< parameters_declaration(c.params) << ") const;" << endl << endl;
return out;
}
+struct comment_constructor_with_constructor_methods
+{
+ eo_class const& _cls;
+ comment_constructor_with_constructor_methods(eo_class const& cls)
+ : _cls(cls)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, comment_constructor_with_constructor_methods const& x)
+{
+ out << tab(1) << "/**" << endl
+ << tab(2) << "@brief Constructs a new " << full_name(x._cls, false) << " object." << endl
+ << endl
+ << tab(2) << "Constructs a new " << full_name(x._cls, false) << " object. If you want this object to be a child" << endl
+ << tab(2) << "of another Eo object, use an @ref efl::eo::parent expression, like the example." << endl
+ << endl;
+
+ if (x._cls.constructors.size())
+ {
+ bool singular = (x._cls.constructors.size() == 1);
+ out << tab(2) << "Since this class have " << (singular ? "a " : "") << "constructor method" << (singular ? "" : "s")
+ << ", you must call " << (singular ? "it" : "each one of them") << endl
+ << tab(2) << "in the right place within this constructor parameters." << endl
+ << endl;
+ }
+
+ out << tab(2) << "Example:" << endl
+ << tab(2) << "@code" << endl
+ << tab(2) << full_name(x._cls, false) << " my_" << x._cls.name << "(" << endl;
+
+ for (eo_constructor const& c : x._cls.constructors)
+ out << tab(3) << "my_" << x._cls.name << "." << c.name << "(" << parameters_names(c.params) << ")," << endl;
+
+ out << tab(3) << "efl::eo::parent = parent_object);" << endl
+ << tab(2) << "@endcode" << endl
+ << endl;
+
+ for (eo_constructor const& c : x._cls.constructors)
+ out << tab(2) << "@see " << x._cls.name << "::" << c.name << endl;
+ out << tab(2) << "@see " << x._cls.name << "(Eo* eo)" << endl;
+
+ return out << tab(1) << "*/" << endl;
+}
+
struct constructor_with_constructor_methods
{
eo_class const& _cls;
cb_count += parameters_count_callbacks((*it).params);
}
+ out << comment_constructor_with_constructor_methods(x._cls);
+
if (cb_count != 0)
{
out << tab(1) << "template <";
inline std::ostream&
operator<<(std::ostream& out, function_call_constructor_methods const& x)
{
+ out << comment("@internal", 1);
+
unsigned cb_count = 0;
constructors_container_type::const_iterator it,
#include <iosfwd>
#include "type_generator.hh"
+#include "eo_class_scope_guard_generator.hh"
#include "tab.hh"
#include "comment.hh"
inline std::ostream&
operator<<(std::ostream& out, event_callback_add const& x)
{
- out << tab(1) << "template <typename F>" << endl
+ out << comment(x._event.comment, 1)
+ << tab(1) << "template <typename F>" << endl
<< tab(1) << "::efl::eo::signal_connection" << endl
<< tab(1) << "callback_" << x._event.name << "_add(F && callback_," << endl
<< tab(8) << "::efl::eo::callback_priority priority_ =" << endl
inline std::ostream&
operator<<(std::ostream& out, event_callback_call const& x)
{
- out << tab(1) << "template <typename T>" << endl
+ out << comment(x._event.comment, 1)
+ << tab(1) << "template <typename T>" << endl
<< tab(1) << "void" << endl
<< tab(1) << "callback_" << x._event.name << "_call(T* info)" << endl
<< tab(1) << "{" << endl
{
for (eo_event const& e : x._events)
{
+ out << scope_guard_head(x._cls, e);
+
out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl
<< event_callback_call(e, x._add_cast_to_t);
+
+ out << scope_guard_tail(x._cls, e) << endl;
}
out << endl;
return out;
#include "parameters_generator.hh"
#include "type_generator.hh"
#include "namespace_generator.hh"
+#include "eo_class_scope_guard_generator.hh"
namespace efl { namespace eolian { namespace grammar {
out << reinterpret_type(func.ret) << " " << func.name << "("
<< parameters_declaration(func.params)
- << (is_static ? ");" : ") const;") << endl << endl;
+ << (is_static ? ");" : ") const;") << endl;
return out;
}
out << tab(1)
<< func.ret.front().native << " _tmp_ret;" << endl;
- if (!is_static)
- out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, 1);
-
- // TODO : register free callback for static methods
+ out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, is_static, 1);
out << tab(1) << "eo_do("
<< (is_static ? "_eo_class(), " : "_concrete_eo_ptr(), ")
if (!function_is_void(func))
out << tab(1) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
- out << "}" << endl << endl;
+ out << "}" << endl;
return out;
}
{
for (eo_function const& f : x._cls.functions)
{
- out << function_declaration(x._cls, f) << endl;
+ out << scope_guard_head(x._cls, f)
+ << function_declaration(x._cls, f)
+ << scope_guard_tail(x._cls, f) << endl;
}
return out;
}
{
for (eo_function const& f : x._cls.functions)
{
- out << function_definition(x._cls, f, x._concrete) << endl;
+ out << scope_guard_head(x._cls, f)
+ << function_definition(x._cls, f, x._concrete)
+ << scope_guard_tail(x._cls, f) << endl;
}
return out;
}
inline std::ostream&
operator<<(std::ostream& out, concrete_eo_ptr_getter const&)
{
- out << tab(1) << "Eo* _concrete_eo_ptr() const" << endl
+ out << comment("@internal", 1)
+ << tab(1) << "Eo* _concrete_eo_ptr() const" << endl
<< tab(1) << "{" << endl
<< tab(2) << "return static_cast<::efl::eo::concrete const*>(static_cast<void const*>(this))->_eo_ptr();" << endl
<< tab(1) << "}" << endl << endl;
inline std::ostream&
operator<<(std::ostream& out, abstract_address_of const& x)
{
+ out << comment("@cond LOCAL", 1);
+
out << tab(1) << "template <typename D>" << endl
<< tab(1) << "struct address_of" << endl
<< tab(1) << "{" << endl
<< tab(1) << "struct address_const_of" << endl
<< tab(1) << "{" << endl
<< tab(2) << address_of_to_pointer(x._cls, true) << endl
- << tab(1) << "};" << endl << endl;
+ << tab(1) << "};" << endl;
+
+ out << comment("@endcond", 1) << endl;
return out;
}
inline std::ostream&
operator<<(std::ostream& out, concrete_address_of const& x)
{
+ out << comment("@cond LOCAL", 1);
std::vector<std::string> names {"address_of", "address_const_of"};
for (int is_const = 0; is_const != 2; ++is_const)
{
<< (is_const ? " const" : "")
<< " { return " << name << "(this); }" << endl << endl;
}
+ out << comment("@endcond", 1) << endl;
return out;
}
inline void
-eo_class_generator(std::ostream& out, eo_class const& cls)
+eo_class_declarations_generator(std::ostream& out, eo_class const& cls)
{
out << namespace_head(cls)
<< "struct " << cls.name << ";" << endl << endl
<< namespace_tail(cls)
+ << comment("@cond EO_CXX_ABSTRACT")
<< "namespace " << abstract_namespace << " {" << endl << endl
<< namespace_head(cls)
<< comment(cls.comment)
<< eo_class_getter(cls)
<< class_implicit_conversion_declaration(cls)
<< abstract_address_of(cls)
- << "private:" << endl
+ << "private:" << endl << endl
<< concrete_eo_ptr_getter(cls)
<< "};" << endl << endl
<< namespace_tail(cls)
- << "}" << endl << endl
+ << "}" << endl
+ << comment("@endcond") << endl
<< namespace_head(cls)
+ << comment(cls.comment, 0, "@brief Class " + cls.name)
<< "struct " << cls.name << endl
<< tab(2) << ": ::efl::eo::concrete" << endl
<< class_inheritance(cls)
<< events(cls, cls.concrete_events) << endl
<< eo_class_getter(cls)
<< concrete_address_of(cls)
- << "private:" << endl
+ << "private:" << endl << endl
<< function_call_constructor_methods(cls)
- << tab(2) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << endl
+ << comment("@internal", 1)
+ << tab(1) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << endl
<< "};" << endl << endl
<< "static_assert(sizeof(" << full_name(cls) << ") == sizeof(Eo*), \"\");" << endl
<< "static_assert(std::is_standard_layout<" << full_name(cls) << ">::value, \"\");" << endl
<< endl
<< namespace_tail(cls)
- << constructor_method_function_definitions(cls)
+ << endl;
+}
+
+inline void
+eo_class_definitions_generator(std::ostream& out, eo_class const& cls)
+{
+ out << constructor_method_function_definitions(cls)
<< function_definitions(cls, true)
<< function_definitions(cls, false)
<< class_implicit_conversion_definition(cls);
--- /dev/null
+#ifndef EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
+#define EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
+
+#include <cassert>
+
+#include "type_generator.hh"
+
+namespace efl { namespace eolian { namespace grammar {
+
+template <typename T>
+struct _scope_guard_head
+{
+ eo_class const& _cls;
+ T const& _e;
+ _scope_guard_head(eo_class const& cls, T const& e)
+ : _cls(cls), _e(e) {}
+};
+
+template <typename T>
+_scope_guard_head<T> scope_guard_head(eo_class const& cls, T const& e)
+{
+ return _scope_guard_head<T>(cls, e);
+}
+
+template <typename T>
+inline std::ostream&
+operator<<(std::ostream& out, _scope_guard_head<T> const& x)
+{
+ assert(x._e.scope != eolian_scope::private_);
+ if (x._e.scope == eolian_scope::protected_)
+ out << "#ifdef " << name_upper(x._cls) << "_PROTECTED" << endl;
+ return out;
+}
+
+template <typename T>
+struct _scope_guard_tail
+{
+ eo_class const& _cls;
+ T const& _e;
+ _scope_guard_tail(eo_class const& cls, T const& e)
+ : _cls(cls), _e(e) {}
+};
+
+template <typename T>
+struct _scope_guard_tail<T> scope_guard_tail(eo_class const& cls, T const& e)
+{
+ return _scope_guard_tail<T>(cls, e);
+}
+
+template <typename T>
+inline std::ostream&
+operator<<(std::ostream& out, _scope_guard_tail<T> const& x)
+{
+ if (x._e.scope == eolian_scope::protected_)
+ out << "#endif" << endl;
+ return out;
+}
+
+} } }
+
+#endif
}
inline void
-eo_header_generator(std::ostream& out, eo_class const& cls, eo_generator_options const& opts)
+include_header_impl(std::ostream& out,
+ eo_class const& cls EINA_UNUSED,
+ eo_generator_options const& opts)
+{
+ out << "#include \"" << opts.header_impl_file_name << "\"" << endl << endl;
+}
+
+inline void
+eo_headers_generator(std::ostream& header_decl,
+ std::ostream& header_impl,
+ eo_class const& cls,
+ eo_generator_options const& opts)
{
- onceguard_head(out, cls);
- include_headers(out, cls, opts);
- eo_class_generator(out, cls);
- eo_inheritance_detail_generator(out, cls);
- onceguard_tail(out, cls);
- out << endl;
+ onceguard_head(header_decl, cls);
+ include_headers(header_decl, cls, opts);
+ eo_class_declarations_generator(header_decl, cls);
+ include_header_impl(header_decl, cls, opts);
+ onceguard_tail(header_decl, cls);
+ header_decl << endl;
+
+ header_impl << comment("@cond EO_CXX_EO_IMPL") << endl;
+ eo_class_definitions_generator(header_impl, cls);
+ eo_inheritance_detail_generator(header_impl, cls);
+ header_impl << endl << comment("@endcond") << endl;
}
} } } // namespace efl { namespace eolian { namespace grammar {
struct inheritance_operation
{
eo_class const& _cls;
+ eo_function const& _func;
functions_container_type::size_type _idx;
- inheritance_operation(eo_class const& cls, functions_container_type::size_type idx)
- : _cls(cls), _idx(idx)
+ inheritance_operation(eo_class const& cls, eo_function const& func, functions_container_type::size_type idx)
+ : _cls(cls), _func(func), _idx(idx)
{}
};
operator<<(std::ostream& out, inheritance_operation const& x)
{
assert(x._idx < x._cls.functions.size());
- eo_function const& func = x._cls.functions[x._idx];
+ eo_function const& func = x._func;
out << tab(1)
<< "ops[" << x._idx << "].func = reinterpret_cast<void*>(& ::"
<< _ns_as_prefix(x._cls) << "_"
<< ", 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)
+
+ auto funcs = x._cls.functions;
+ auto part = std::stable_partition(funcs.begin(), funcs.end(), [](eo_function const& f){ return f.scope == eolian_scope::public_; });
+
+ functions_container_type::size_type op_idx = 0;
+ for (auto it = funcs.begin(); it != part; ++it, ++op_idx)
{
- out << inheritance_operation(x._cls, i);
+ out << inheritance_operation(x._cls, *it, op_idx);
+ }
+
+ if (part != funcs.end())
+ {
+ out << scope_guard_head(x._cls, *part);
+ for (auto it = part; it != funcs.end(); ++it, ++op_idx)
+ out << inheritance_operation(x._cls, *it, op_idx);
+ out << scope_guard_tail(x._cls, *part);
}
for (std::string const& parent : x._cls.parents)
{
out << tab(1)
<< "initialize_operation_description<T>(::efl::eo::detail::tag<::"
- << parent << ">(), &ops[" << x._cls.functions.size() << s << "]);" << endl;
+ << parent << ">(), &ops[operation_description_class_size< "
+ << full_name(x._cls) << " >::value" << s << "]);" << endl;
s += " + operation_description_class_size<::" + parent + ">::value";
}
for (it = first; it != last; ++it)
{
eo_function const& func = *it;
+
+ out << scope_guard_head(x._cls, func);
+
out << "template <typename T>" << endl
<< reinterpret_type(func.ret) << " "
<< _ns_as_prefix(x._cls) << "_"
if (!function_is_void(func))
out << tab(1) << "return _tmp_ret;" << endl;
- out << "}" << endl << endl;
+ out << "}" << endl;
+
+ out << scope_guard_tail(x._cls, func) << endl;
}
return out;
}
struct inheritance_base_operations_size
{
eo_class const& _cls;
- inheritance_base_operations_size(eo_class const& cls)
- : _cls(cls)
+ functions_container_type const& _funcs;
+ inheritance_base_operations_size(eo_class const& cls, functions_container_type const& funcs)
+ : _cls(cls), _funcs(funcs)
{}
};
<< endl << "struct operation_description_class_size< "
<< full_name(x._cls) << " >" << endl
<< "{" << endl
- << tab(1) << "static const int value = "
- << x._cls.functions.size();
+ << tab(1) << "static constexpr int value = "
+ << x._funcs.size();
for (std::string const& parent : x._cls.parents)
{
return out;
}
+struct inheritance_base_operations_size_scopes
+{
+ eo_class const& _cls;
+ inheritance_base_operations_size_scopes(eo_class const& cls)
+ : _cls(cls)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, inheritance_base_operations_size_scopes const& x)
+{
+ auto funcs = x._cls.functions;
+ auto part = std::stable_partition(funcs.begin(), funcs.end(), [](eo_function const& f){ return f.scope == eolian_scope::public_; });
+
+ out << "#ifdef " << name_upper(x._cls) << "_PROTECTED" << endl
+ << inheritance_base_operations_size(x._cls, funcs)
+ << "#else" << endl
+ << inheritance_base_operations_size(x._cls, {funcs.begin(), part})
+ << "#endif" << endl << endl;
+ return out;
+}
struct inheritance_base_operations_extensions
{
if (!is_void)
out << tab(3) << func.ret.front().native << " _tmp_ret = {};" << endl;
- out << callbacks_heap_alloc("dynamic_cast<T*>(this)->_eo_ptr()", func.params, 3)
+ out << callbacks_heap_alloc("dynamic_cast<T*>(this)->_eo_ptr()", func.params, function_is_static(x._func), 3)
<< endl;
out << tab(3)
if (!is_void)
out << tab(4) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
- return out << tab(2) << "}" << endl << endl;
+ return out << tab(2) << "}" << endl;
}
struct inheritance_base_operations
last = x._cls.functions.end();
for (it = first; it != last; ++it)
{
+ out << scope_guard_head(x._cls, *it);
out << inheritance_base_operations_function(x._cls, *it);
+ out << scope_guard_tail(x._cls, *it) << endl;
}
out << tab(1) << "};" << endl
<< "};" << endl << endl;
out << inheritance_wrappers(cls)
<< "namespace efl { namespace eo { namespace detail {" << endl << endl
<< inheritance_base_operations(cls) << endl
- << inheritance_base_operations_size(cls)
+ << inheritance_base_operations_size_scopes(cls)
<< inheritance_operations_description(cls)
<< inheritance_call_constructors(cls)
<< inheritance_eo_class_getter(cls)
return out << "_tmp_" << x._name;
}
-struct
-callback_parameter_heap_alloc
-{
- eolian_type_instance const& _type;
- std::string const& _name;
- int _tab;
- callback_parameter_heap_alloc(eolian_type_instance const& type, std::string const& name, int tab)
- : _type(type)
- , _name(name)
- , _tab(tab)
- {}
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, callback_parameter_heap_alloc const& x)
-{
- out << tab(x._tab) << parameter_remove_reference_typedef(x._type, x._name) << endl
- << tab(x._tab) << parameter_no_ref_type(x._type, x._name) << "* "
- << callback_tmp(x._name) << " = new "
- << parameter_no_ref_type(x._type, x._name) << "(std::forward<"
- << template_parameter_type(x._type, x._name) << ">(" << x._name << "));" << endl;
- return out;
-}
-
struct
callback_parameter_free_ev_add
{
{
std::string const& _eo_raw_expr;
parameters_container_type const& _params;
+ bool _is_static_func;
int _tab;
- callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, int tab)
+ callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, bool is_static_func, int tab)
: _eo_raw_expr(eo_raw_expr)
, _params(params)
+ , _is_static_func(is_static_func)
, _tab(tab)
{}
};
auto first = x._params.cbegin(), last = x._params.cend();
for (auto it = first; it != last; ++it)
{
- if (type_is_callback((*it).type) && it+1 != last)
+ auto type = (*it).type;
+ auto name = (*it).name;
+ if (type_is_callback(type) && it+1 != last)
{
- out << callback_parameter_heap_alloc((*it).type, (*it).name, x._tab)
- << tab(x._tab)
- << callback_parameter_free_ev_add(x._eo_raw_expr, (*it).type, (*it).name)
- << endl << endl;
+
+ out << tab(x._tab) << parameter_remove_reference_typedef(type, name) << endl
+ << tab(x._tab) << parameter_no_ref_type(type, name) << "* "
+ << callback_tmp(name) << " = ";
+
+ if (!x._is_static_func)
+ {
+ out << "new " << parameter_no_ref_type(type, name)
+ << "(std::forward< "
+ << template_parameter_type(type, name) << " >(" << name << "));" << endl
+ << tab(x._tab)
+ << callback_parameter_free_ev_add(x._eo_raw_expr, type, name)
+ << endl << endl;
+ }
+ else
+ {
+ out << "::efl::eolian::alloc_static_callback< "
+ << parameter_no_ref_type(type, name) << " >(std::forward< "
+ << template_parameter_type(type, name) << " >(" << name << "));" << endl;
+ }
++it; // skip next.
}
}
return out;
}
+struct
+parameters_names
+{
+ parameters_container_type const& _params;
+ parameters_names(parameters_container_type const& params)
+ : _params(params)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameters_names const& x)
+{
+ auto first = x._params.cbegin(),
+ last = x._params.cend();
+ for (auto it = first; it != last; ++it)
+ {
+ if (it != first)
+ out << ", ";
+
+ out << it->name;
+
+ if (type_is_callback(it->type) && it+1 != last)
+ ++it; // skip next.
+ }
+ return out;
+}
+
+struct
+parameters_c_names
+{
+ parameters_container_type const& _params;
+ parameters_c_names(parameters_container_type const& params)
+ : _params(params)
+ {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameters_c_names const& x)
+{
+ auto first = x._params.cbegin(),
+ last = x._params.cend();
+ for (auto it = first; it != last; ++it)
+ {
+ if (it != first)
+ out << ", ";
+ out << it->name;
+ }
+ return out;
+}
+
struct
parameters_types
{
return out << abstract_namespace << full_name(x._cls);
}
+struct name_upper
+{
+ eo_class const& _cls;
+ name_upper(eo_class const& cls)
+ : _cls(cls) {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, name_upper const& x)
+{
+ std::string key = x._cls.name;
+ std::transform(key.begin(), key.end(), key.begin(), ::toupper);
+ return out << key;
+}
+
struct c_type
{
eolian_type_instance const& _list;
}
assert(!res.empty());
- if (x._type.is_out && type_is_binding(x._type.front()))
- res += "*";
- else if (!x._type.is_nonull && x._type.front().is_class)
- res = "::efl::eina::optional< " + res + " >";
+ if (type_is_binding(x._type.front()))
+ {
+ if (x._type.is_out)
+ res += "*";
+ else if (!x._type.is_nonull && x._type.front().binding_requires_optional)
+ res = "::efl::eina::optional< " + res + " >";
+ }
return out << res;
}
cb(data);
}
+static void _callback_test_global_callbacks(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED
+ , Ecore_Cb cb, void *data)
+{
+ cb(data);
+}
+
#include "callback.eo.c"
@in Ecore_Cb cb2;
}
}
+ test_global_callbacks @class {
+ params {
+ @in Ecore_Cb cb;
+ @in void* data;
+ }
+ }
}
implements {
Eo.Base.constructor;
}
END_TEST
+START_TEST(eolian_cxx_test_global_callback)
+{
+ efl::eo::eo_init i;
+
+ bool called = false;
+
+ callback::test_global_callbacks(std::bind([&called] { called = true; }));
+
+ fail_if(!called);
+}
+END_TEST
+
void
eolian_cxx_test_callback(TCase* tc)
{
tcase_add_test(tc, eolian_cxx_test_callback_method);
tcase_add_test(tc, eolian_cxx_test_callback_event_add);
tcase_add_test(tc, eolian_cxx_test_callback_event_del);
+ tcase_add_test(tc, eolian_cxx_test_global_callback);
}