efl_mono: tests and better support for structs, plus some other fixes

Fix several integer binding type deduction based in its size on C.

Generation for function pointers no longer use modified argument name
which is different from the parameter name.

New generation context for structs.

bool from UnmanagedType.I1 to UnmanagedType.U1 (correct use
inside structs according to mono documentation).

byte (signed char) and int8 now is correctly represented by
sbyte in C#.

Check parameter direction in some out generators in parameter.hh.

Add efl_libs.csv to gitignore.

Make eina.Value pointer constructor public.

Add missing fields to efl.kw_event.Description struct.

Remove eina.File workaround (let struct gen handle it).

Remove is_function_ptr bool from regular_type_def and
add a typedecl_type enum to it. Also add some helper
methods for easier comparison.

Left some test cases commented for when pointer parameters
are properly working.
This commit is contained in:
Vitor Sousa 2017-12-12 12:06:46 -02:00
parent b20dd869a4
commit acd99be98b
19 changed files with 1616 additions and 100 deletions

View File

@ -371,6 +371,7 @@ tests_efl_mono_efl_mono_exe_SOURCES = \
tests/efl_mono/Events.cs \
tests/efl_mono/FunctionPointers.cs \
tests/efl_mono/Strings.cs \
tests/efl_mono/Structs.cs \
tests/efl_mono/TestUtils.cs \
tests/efl_mono/Value.cs \
tests/efl_mono/ValueEolian.cs

View File

@ -69,14 +69,14 @@ struct function_pointer {
<< scope_tab << "public " << type << " ManagedCb(" << (parameter % ",") << ")\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation % ", ") << ");\n"
<< scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation_no_conversion % ", ") << ");\n"
<< scope_tab << "}\n\n"
<< scope_tab << "public static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
<< scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n"
<< scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation % ", ") << ");\n"
<< scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation_no_conversion % ", ") << ");\n"
<< scope_tab << "}\n"
<< "}\n"
).generate(sink, std::make_tuple(f.return_type, f.parameters, f.parameters, f.return_type, f.parameters, f_name, f_name, f.parameters), context))

View File

@ -10,6 +10,7 @@ struct class_context
concrete,
inherit,
inherit_native,
structs,
};
wrapper_kind current_wrapper_kind;
};

View File

@ -0,0 +1,59 @@
#ifndef EOLIAN_MONO_HELPERS_HH
#define EOLIAN_MONO_HELPERS_HH
#include "grammar/klass_def.hpp"
namespace eolian_mono {
namespace attributes = efl::eolian::grammar::attributes;
inline std::string type_full_name(attributes::regular_type_def const& type)
{
std::string full_name;
for (auto& name : type.namespaces)
{
full_name += name + ".";
}
full_name += type.base_type;
return full_name;
}
inline std::string struct_full_name(attributes::struct_def const& struct_)
{
std::string full_name;
for (auto& name : struct_.namespaces)
{
full_name += name + ".";
}
full_name += struct_.cxx_name;
return full_name;
}
// Blacklist structs that require some kind of manual binding.
inline bool is_struct_blacklisted(std::string const& full_name)
{
return full_name == "Efl.Event.Description"
// || full_name == "Eina.File"
|| full_name == "Eina.Binbuf"
|| full_name == "Eina.Slice"
|| full_name == "Eina.Rw_Slice";
}
inline bool is_struct_blacklisted(attributes::struct_def const& struct_)
{
return is_struct_blacklisted(struct_full_name(struct_));
}
inline bool is_struct_blacklisted(attributes::regular_type_def const& struct_)
{
return is_struct_blacklisted(type_full_name(struct_));
}
inline bool need_struct_conversion(attributes::regular_type_def const* regular)
{
return regular && regular->is_struct() && !is_struct_blacklisted(*regular);
}
}
#endif

View File

@ -51,7 +51,7 @@ struct marshall_annotation_visitor_generate
match const parameter_match_table[] =
{
// signed primitives
{"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.I1)]"; }},
{"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
{"string", true, [&] {
return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
}},
@ -80,7 +80,7 @@ struct marshall_annotation_visitor_generate
match const return_match_table[] =
{
// signed primitives
{"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.I1)]"; }},
{"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
{"string", true, [&] {
return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
}},
@ -170,7 +170,7 @@ struct marshall_native_annotation_visitor_generate
match const parameter_match_table[] =
{
// signed primitives
{"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.I1)]"; }},
{"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
{"string", true, [&] {
return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
}},
@ -191,7 +191,7 @@ struct marshall_native_annotation_visitor_generate
match const return_match_table[] =
{
// signed primitives
{"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.I1)]"; }},
{"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
{"string", true, [&] {
return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
}},

View File

@ -4,6 +4,7 @@
#include "grammar/generator.hpp"
#include "grammar/klass_def.hpp"
#include "grammar/case.hpp"
#include "helpers.hh"
#include "namespace.hh"
#include "type_impl.hh"
#include "generation_contexts.hh"
@ -148,7 +149,12 @@ struct marshall_type_visitor_generate
}}
};
if(eina::optional<bool> b = call_match
if (regular.is_struct() && !is_struct_blacklisted(regular))
{
return as_generator(*(lower_case[string] << ".") << string << "_StructInternal")
.generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context);
}
else if (eina::optional<bool> b = call_match
(match_table
, [&] (match const& m)
{

View File

@ -4,6 +4,7 @@
#include "grammar/generator.hpp"
#include "grammar/klass_def.hpp"
#include "grammar/case.hpp"
#include "helpers.hh"
#include "marshall_type.hh"
#include "type.hh"
#include "using_decl.hh"
@ -226,6 +227,9 @@ inline bool param_is_acceptable(attributes::parameter_def const &param, std::str
inline bool param_should_use_out_var(attributes::parameter_def const& param, bool native)
{
if (param.direction == attributes::parameter_direction::in)
return false;
if ((native && param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
|| (native && param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@ -261,11 +265,18 @@ inline bool param_should_use_out_var(attributes::parameter_def const& param, boo
)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular))
return true;
return false;
}
inline bool param_should_use_in_var(attributes::parameter_def const& param, bool /*native*/)
{
if (param.direction != attributes::parameter_direction::in)
return false;
if (param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
@ -299,6 +310,10 @@ inline bool param_should_use_in_var(attributes::parameter_def const& param, bool
)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular))
return true;
return false;
}
@ -320,7 +335,9 @@ inline std::string direction_modifier(attributes::parameter_def const& param)
}
else if (param.direction != attributes::parameter_direction::in)
{
if (param.type.c_type == "Eina_Slice" || param.type.c_type == "Eina_Rw_Slice")
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param.type.c_type == "Eina_Slice" || param.type.c_type == "Eina_Rw_Slice"
|| need_struct_conversion(regular))
return " ref ";
else
return " out ";
@ -335,7 +352,7 @@ struct is_fp_visitor
bool operator()(grammar::attributes::regular_type_def const &type) const
{
return type.is_function_ptr;
return type.is_function_ptr();
}
template<typename T>
@ -445,14 +462,18 @@ struct native_argument_invocation_generator
// Generates the correct parameter name when invoking a function
struct argument_invocation_generator
{
constexpr argument_invocation_generator(bool conversion_vars)
: use_conversion_vars(conversion_vars)
{}
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
std::string arg = direction_modifier(param);
if (param_should_use_out_var(param, false))
if (use_conversion_vars && param_should_use_out_var(param, false))
arg += out_variable_name(param.param_name);
else if (param_should_use_in_var(param, false))
else if (use_conversion_vars && param_should_use_in_var(param, false))
arg += in_variable_name(param.param_name);
else if (param.type.original_type.visit(is_fp_visitor{}))
{
@ -465,7 +486,11 @@ struct argument_invocation_generator
return as_generator(arg).generate(sink, attributes::unused, context);
}
} const argument_invocation {};
bool const use_conversion_vars;
} const argument_invocation {true};
argument_invocation_generator const argument_invocation_no_conversion {false};
struct native_convert_in_variable_generator
{
@ -475,7 +500,14 @@ struct native_convert_in_variable_generator
if (param.direction != attributes::parameter_direction::in)
return true;
if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
{
return as_generator(
"var " << string << " = new eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
@ -530,7 +562,14 @@ struct convert_in_variable_generator
if (param.direction != attributes::parameter_direction::in)
return true;
if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
{
auto var_name = in_variable_name(param.param_name);
if (!as_generator(
@ -608,7 +647,17 @@ struct convert_out_variable_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = new " << marshall_type << "();\n"
).generate(sink, std::make_tuple(out_variable_name(param.param_name), param.type), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@ -665,7 +714,12 @@ struct native_convert_out_variable_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular)
|| param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
{
return as_generator(
@ -740,7 +794,17 @@ struct convert_out_assign_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular))
{
return as_generator(
string << " = " << type << "_StructConvertion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@ -829,7 +893,14 @@ struct convert_return_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
if (need_struct_conversion(regular))
{
return as_generator(
"return " << type << "_StructConvertion.ToExternal(_ret_var);\n"
).generate(sink, ret_type, context);
}
else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
{
if (!as_generator("var _binbuf_ret = new eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n"
<< scope_tab << scope_tab << "return _binbuf_ret;\n")
@ -881,7 +952,17 @@ struct native_convert_out_assign_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (need_struct_conversion(regular))
{
return as_generator(
string << " = " << type << "_StructConvertion.ToInternal(" << string << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
{
return as_generator(
string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << string << "Inherit)wrapper).cached_stringshares, " << string << ");\n"
@ -1001,7 +1082,14 @@ struct native_convert_return_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
if (ret_type.c_type == "const char *")
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
if (need_struct_conversion(regular))
{
return as_generator(
"return " << type << "_StructConvertion.ToInternal(_ret_var);\n"
).generate(sink, ret_type, context);
}
else if (ret_type.c_type == "const char *")
{
if(!ret_type.has_own)
{

View File

@ -6,28 +6,28 @@
#include "grammar/indentation.hpp"
#include "grammar/list.hpp"
#include "grammar/alternative.hpp"
#include "helpers.hh"
#include "type.hh"
#include "keyword.hh"
#include "using_decl.hh"
namespace eolian_mono {
// Blacklist structs that require some kind of manual binding.
static bool is_struct_blacklisted(attributes::struct_def const& struct_)
inline std::string binding_struct_name(attributes::struct_def const& struct_)
{
std::string full_name;
return struct_.cxx_name;
}
for (auto it=struct_.namespaces.begin(); it != struct_.namespaces.end(); it++)
{
full_name += *it + ".";
}
inline std::string binding_struct_internal_name(attributes::struct_def const& struct_)
{
return struct_.cxx_name + "_StructInternal";
}
full_name += struct_.cxx_name;
return full_name == "Efl.Event.Description"
|| full_name == "Eina.File"
|| full_name == "Eina.Binbuf"
|| full_name == "Eina.Slice"
|| full_name == "Eina.Rw_Slice";
inline std::string to_field_name(std::string const& in)
{
std::string field_name = in;
field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
return field_name;
}
struct struct_definition_generator
@ -35,33 +35,22 @@ struct struct_definition_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
if (is_struct_blacklisted(struct_))
return true;
std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(struct_.namespaces));
auto open_namespace = *("namespace " << string << " { ") << "\n";
if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false;
if(!as_generator
(
"[StructLayout(LayoutKind.Sequential)]\n"
"public struct " << string << "\n{\n"
)
.generate(sink, struct_.cxx_name, context))
.generate(sink, binding_struct_name(struct_), context))
return false;
// iterate struct fields
for(auto first = std::begin(struct_.fields)
, last = std::end(struct_.fields); first != last; ++first)
for (auto const& field : struct_.fields)
{
auto field_name = (*first).name;
auto field_type = (*first).type;
field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
if (!as_generator
(
"public " << type << " " << string << ";\n"
" public " << type << " " << string << ";\n"
)
.generate(sink, std::make_tuple(field_type, field_name), context))
.generate(sink, std::make_tuple(field.type, to_field_name(field.name)), context))
return false;
}
@ -77,14 +66,354 @@ struct struct_definition_generator
if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
return true;
}
} const struct_definition {};
struct struct_internal_definition_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
if (!as_generator
(
"[StructLayout(LayoutKind.Sequential)]\n"
"public struct " << string << "\n{\n"
)
.generate(sink, binding_struct_internal_name(struct_), context))
return false;
// iterate struct fields
for (auto const& field : struct_.fields)
{
auto field_name = to_field_name(field.name);
auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
if (klass
|| (regular && (regular->base_type == "string"
|| regular->base_type == "mstring"
|| regular->base_type == "stringshare"
|| regular->base_type == "any_value_ptr")))
{
if (!as_generator(" public System.IntPtr " << string << ";\n")
.generate(sink, field_name, context))
return false;
}
else if (!as_generator(eolian_mono::marshall_annotation(false) << " public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
.generate(sink, std::make_tuple(field.type, field.type, field_name), context))
return false;
}
// Check whether this is an extern struct without declared fields in .eo file and generate a
// placeholder field if positive.
// Mono's JIT is picky when generating function pointer for delegates with empty structs, leading to
// those 'mini-amd64.c condition fields not met' crashes.
if (struct_.fields.size() == 0)
{
if (!as_generator("public IntPtr field;\n").generate(sink, nullptr, context))
return false;
}
if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
return true;
}
} const struct_internal_definition {};
// Conversors generation //
struct to_internal_field_convert_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
{
auto field_name = to_field_name(field.name);
auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
auto complex = efl::eina::get<attributes::complex_type_def>(&field.type.original_type);
if (klass)
{
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".raw_handle;\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if ((complex && (complex->outer.base_type == "array"
|| complex->outer.base_type == "inarray"
|| complex->outer.base_type == "list"
|| complex->outer.base_type == "inlist"
|| complex->outer.base_type == "iterator"
|| complex->outer.base_type == "hash"))
|| field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
{
// Always assumes pointer
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".Handle;\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (need_struct_conversion(regular))
{
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = " << type << "_StructConvertion.ToInternal(_external_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
else if (regular && (regular->base_type == "string" || regular->base_type == "mstring"))
{
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = eina.MemoryNative.StrDup(_external_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (regular && regular->base_type == "stringshare")
{
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = eina.Stringshare.eina_stringshare_add(_external_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
|| field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
{
if (!as_generator(
"\n" <<
scope_tab << scope_tab << "_internal_struct." << field_name << ".Len = _external_struct." << field_name << ".Len;\n" <<
scope_tab << scope_tab << "_internal_struct." << field_name << ".Mem = _external_struct." << field_name << ".Mem;\n\n")
.generate(sink, attributes::unused, context))
return false;
}
else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
{
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".GetNative();\n"
).generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
{
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".Handle;\n"
).generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else // primitives and enums
{
if (!as_generator(
scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ";\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
return true;
}
} const to_internal_field_convert {};
struct to_external_field_convert_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
{
auto field_name = to_field_name(field.name);
auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
auto complex = efl::eina::get<attributes::complex_type_def>(&field.type.original_type);
if (klass)
{
if (!as_generator(
"\n"
<< scope_tab << scope_tab << "_external_struct." << string
<< " = (" << type << ") System.Activator.CreateInstance(typeof("
<< type << "Concrete), new System.Object[] {_internal_struct." << string << "});\n"
<< scope_tab << scope_tab << "efl.eo.Globals.efl_ref(_internal_struct." << string << ");\n\n")
.generate(sink, std::make_tuple(field_name, field.type, field.type, field_name, field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false);\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
else if (complex && (complex->outer.base_type == "array"
|| complex->outer.base_type == "inarray"
|| complex->outer.base_type == "list"
|| complex->outer.base_type == "inlist"
|| complex->outer.base_type == "iterator"))
{
// Always assumes pointer
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false);\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
else if (complex && complex->outer.base_type == "hash")
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false, false);\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
else if (need_struct_conversion(regular))
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConvertion.ToExternal(_internal_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
else if (regular && (regular->base_type == "string" || regular->base_type == "mstring" || regular->base_type == "stringshare"))
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = eina.StringConversion.NativeUtf8ToManagedString(_internal_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
|| field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
{
if (!as_generator(
"\n" <<
scope_tab << scope_tab << "_external_struct." << field_name << ".Len = _internal_struct." << field_name << ".Len;\n" <<
scope_tab << scope_tab << "_external_struct." << field_name << ".Mem = _internal_struct." << field_name << ".Mem;\n\n")
.generate(sink, attributes::unused, context))
return false;
}
else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ");\n"
).generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ", eina.ValueOwnership.Unmanaged);\n"
).generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else // primitives and enums
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << ";\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
return true;
}
} const to_external_field_convert {};
struct struct_binding_conversion_functions_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
// Open conversion class
if (!as_generator
(
"public static class " << string << "_StructConvertion\n{\n"
)
.generate(sink, struct_.cxx_name, context))
return false;
// to internal
if (!as_generator
(
scope_tab << "public static " << string << " ToInternal(" << string << " _external_struct)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var _internal_struct = new " << string << "();\n\n"
)
.generate(sink, std::make_tuple(binding_struct_internal_name(struct_)
, binding_struct_name(struct_)
, binding_struct_internal_name(struct_)
), context))
return false;
for (auto const& field : struct_.fields)
{
if (!to_internal_field_convert.generate(sink, field, context))
return false;
}
if (!as_generator
(
"\n"
<< scope_tab << scope_tab << "return _internal_struct;\n"
<< scope_tab << "}\n\n"
)
.generate(sink, attributes::unused, context))
return false;
// to external
if (!as_generator
(
scope_tab << "public static " << string << " ToExternal(" << string << " _internal_struct)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var _external_struct = new " << string << "();\n\n"
)
.generate(sink, std::make_tuple(binding_struct_name(struct_)
, binding_struct_internal_name(struct_)
, binding_struct_name(struct_)
), context))
return false;
for (auto const& field : struct_.fields)
{
if (!to_external_field_convert.generate(sink, field, context))
return false;
}
if (!as_generator
(
"\n"
<< scope_tab << scope_tab << "return _external_struct;\n"
<< scope_tab << "}\n\n"
)
.generate(sink, attributes::unused, context))
return false;
// Close conversion class
if (!as_generator("}\n").generate(sink, attributes::unused, context))
return false;
return true;
}
} const struct_binding_conversion_functions {};
struct struct_entities_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
if (is_struct_blacklisted(struct_))
return true;
std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(struct_.namespaces));
auto open_namespace = *("namespace " << string << " { ") << "\n";
if (!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context)))
return false;
if (!struct_definition.generate(sink, struct_, context))
return false;
if (!struct_internal_definition.generate(sink, struct_, context))
return false;
if (!struct_binding_conversion_functions.generate(sink, struct_, context))
return false;
auto close_namespace = *(lit("} ")) << "\n";
if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false;
return true;
}
};
struct_definition_generator const struct_definition = {};
} const struct_entities {};
}
@ -95,9 +424,49 @@ struct is_eager_generator< ::eolian_mono::struct_definition_generator> : std::tr
template <>
struct is_generator< ::eolian_mono::struct_definition_generator> : std::true_type {};
template <>
struct is_eager_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
template <>
struct is_eager_generator< ::eolian_mono::to_internal_field_convert_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::to_internal_field_convert_generator> : std::true_type {};
template <>
struct is_eager_generator< ::eolian_mono::to_external_field_convert_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::to_external_field_convert_generator> : std::true_type {};
template <>
struct is_eager_generator< ::eolian_mono::struct_binding_conversion_functions_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::struct_binding_conversion_functions_generator> : std::true_type {};
template <>
struct is_eager_generator< ::eolian_mono::struct_entities_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::struct_entities_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::struct_definition_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::struct_internal_definition_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::to_internal_field_convert_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::to_external_field_convert_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::struct_binding_conversion_functions_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::struct_entities_generator> : std::integral_constant<int, 1> {};
}
} } }

View File

@ -13,12 +13,28 @@ namespace eina = efl::eina;
template <typename T>
T const* as_const_pointer(T* p) { return p; }
inline
attributes::regular_type_def replace_base_type(attributes::regular_type_def v, std::string name)
{
v.base_type = name;
return v;
}
template <typename T>
attributes::regular_type_def replace_base_integer(attributes::regular_type_def v)
{
bool s = std::is_signed<T>::value;
switch (sizeof(T))
{
case 1: return s ? replace_base_type(v, " sbyte") : replace_base_type(v, " byte");
case 2: return s ? replace_base_type(v, " short") : replace_base_type(v, " ushort");
case 4: return s ? replace_base_type(v, " int") : replace_base_type(v, " uint");
case 8: return s ? replace_base_type(v, " long") : replace_base_type(v, " ulong");
default: return v;
}
}
inline
attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular)
{
v.outer = regular;
@ -62,26 +78,29 @@ struct visitor_generate
const match_table[] =
{
// signed primitives
{"byte", nullptr, [&] { return replace_base_type(regular, " byte"); }}
, {"llong", nullptr, [&] { return replace_base_type(regular, " long"); }}
, {"int8", nullptr, [&] { return replace_base_type(regular, " byte"); }}
{"byte", nullptr, [&] { return replace_base_type(regular, " sbyte"); }}
, {"short", nullptr, [&] { return replace_base_integer<short>(regular); }}
, {"int", nullptr, [&] { return replace_base_integer<int>(regular); }}
, {"long", nullptr, [&] { return replace_base_integer<long>(regular); }}
, {"llong", nullptr, [&] { return replace_base_integer<long long>(regular); }}
, {"int8", nullptr, [&] { return replace_base_type(regular, " sbyte"); }}
, {"int16", nullptr, [&] { return replace_base_type(regular, " short"); }}
, {"int32", nullptr, [&] { return replace_base_type(regular, " int"); }}
, {"int64", nullptr, [&] { return replace_base_type(regular, " long"); }}
, {"ssize", nullptr, [&] { return replace_base_type(regular, " long"); }}
, {"ssize", nullptr, [&] { return replace_base_integer<ssize_t>(regular); }}
// unsigned primitives
, {"ubyte", nullptr, [&] { return replace_base_type(regular, " byte"); }}
, {"ushort", nullptr, [&] { return replace_base_type(regular, " ushort"); }}
, {"uint", nullptr, [&] { return replace_base_type(regular, " uint"); }}
, {"ulong", nullptr, [&] { return replace_base_type(regular, " ulong"); }}
, {"ullong", nullptr, [&] { return replace_base_type(regular, " ulong"); }}
, {"ushort", nullptr, [&] { return replace_base_integer<unsigned short>(regular); }}
, {"uint", nullptr, [&] { return replace_base_integer<unsigned int>(regular); }}
, {"ulong", nullptr, [&] { return replace_base_integer<unsigned long>(regular); }}
, {"ullong", nullptr, [&] { return replace_base_integer<unsigned long long>(regular); }}
, {"uint8", nullptr, [&] { return replace_base_type(regular, " byte"); }}
, {"uint16", nullptr, [&] { return replace_base_type(regular, " ushort"); }}
, {"uint32", nullptr, [&] { return replace_base_type(regular, " uint"); }}
, {"uint64", nullptr, [&] { return replace_base_type(regular, " ulong"); }}
, {"size", nullptr, [&] { return replace_base_type(regular, " ulong"); }}
, {"size", nullptr, [&] { return replace_base_integer<size_t>(regular); }}
, {"ptrdiff", nullptr, [&] { return replace_base_type(regular, " long"); }}
, {"ptrdiff", nullptr, [&] { return replace_base_integer<ptrdiff_t>(regular); }}
, {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
, {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
, {"void", nullptr, [&]

View File

@ -183,7 +183,8 @@ run(options_type const& opts)
, struct_last; struct_iterator != struct_last; ++struct_iterator)
{
efl::eolian::grammar::attributes::struct_def struct_(&*struct_iterator, opts.unit);
if (!eolian_mono::struct_definition.generate(iterator, struct_, efl::eolian::grammar::context_null()))
auto structs_cxt = context_add_tag(class_context{class_context::structs}, context);
if (!eolian_mono::struct_entities.generate(iterator, struct_, structs_cxt))
{
throw std::runtime_error("Failed to generate struct");
}

View File

@ -1 +1,2 @@
/efl_libs.cs
/efl_libs.csv

View File

@ -681,7 +681,7 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
this.Ownership = ValueOwnership.Managed;
}
internal Value(IntPtr handle, ValueOwnership ownership=ValueOwnership.Managed) {
public Value(IntPtr handle, ValueOwnership ownership=ValueOwnership.Managed) {
this.Handle = handle;
this.Ownership = ownership;
}

View File

@ -59,7 +59,10 @@ namespace efl { namespace kw_event {
[StructLayout(LayoutKind.Sequential)]
public struct Description {
IntPtr pointer; // Opaque type, just pass the pointer. What about hot/freeze/etc?
public IntPtr Name;
[MarshalAs(UnmanagedType.U1)] public bool Unfreezable;
[MarshalAs(UnmanagedType.U1)] public bool Legacy_is;
[MarshalAs(UnmanagedType.U1)] public bool Restart;
private static Dictionary<string, IntPtr> descriptions = new Dictionary<string, IntPtr>();
@ -76,7 +79,10 @@ public struct Description {
descriptions.Add(name, data);
}
this.pointer = descriptions[name];
this.Name = descriptions[name];
this.Unfreezable = false;
this.Legacy_is = false;
this.Restart = false;
}
};
@ -241,6 +247,7 @@ public struct Efl_Font_Size {
namespace eina {
[StructLayout(LayoutKind.Sequential)]
public struct Rectangle {
public int x;
public int y;
@ -250,12 +257,6 @@ public struct Rectangle {
}
namespace eina {
public interface File {}
}
namespace evas {
/* Copied from Evas_Legacy.h */

View File

@ -26,7 +26,7 @@ struct converting_argument_generator
bool operator()(T const&) const { return false;}
bool operator()(attributes::regular_type_def const& r) const
{
return r.is_function_ptr;
return r.is_function_ptr();
}
} static const is_function_ptr;
template <typename OutputIterator, typename Context>

View File

@ -24,7 +24,7 @@ namespace efl { namespace eolian { namespace grammar {
namespace attributes {
struct complex_type_def;
}
namespace attributes {
@ -64,16 +64,44 @@ bool lexicographical_compare(std::tuple<T, U> const& lhs
|| (!(std::get<0>(rhs) < std::get<0>(lhs))
&& std::get<1>(lhs) < std::get<1>(rhs));
}
enum class typedecl_type
{
unknown,
struct_,
struct_opaque,
enum_,
alias,
function_ptr,
};
inline typedecl_type typedecl_type_get(Eolian_Typedecl const* decl)
{
if (!decl)
return typedecl_type::unknown;
Eolian_Typedecl_Type t = eolian_typedecl_type_get(decl);
switch (t)
{
case EOLIAN_TYPEDECL_UNKNOWN: return typedecl_type::unknown;
case EOLIAN_TYPEDECL_STRUCT: return typedecl_type::struct_;
case EOLIAN_TYPEDECL_STRUCT_OPAQUE: return typedecl_type::struct_opaque;
case EOLIAN_TYPEDECL_ENUM: return typedecl_type::enum_;
case EOLIAN_TYPEDECL_ALIAS: return typedecl_type::alias;
case EOLIAN_TYPEDECL_FUNCTION_POINTER: return typedecl_type::function_ptr;
default: return typedecl_type::unknown;
}
}
struct type_def;
bool operator==(type_def const& rhs, type_def const& lhs);
bool operator!=(type_def const& rhs, type_def const& lhs);
enum class class_type
{
regular, abstract_, mixin, interface_
};
struct klass_name
{
std::vector<std::string> namespaces;
@ -168,19 +196,28 @@ get(klass_name const& klass)
{
return tuple_element<N, klass_name>::get(klass);
}
struct regular_type_def
{
regular_type_def() : is_undefined(false), is_function_ptr(false) {}
regular_type_def() : type_type(typedecl_type::unknown), is_undefined(false) {}
regular_type_def(std::string base_type, qualifier_def qual, std::vector<std::string> namespaces
, bool is_undefined = false, bool is_function_ptr = false)
, typedecl_type type_type = typedecl_type::unknown, bool is_undefined = false)
: base_type(std::move(base_type)), base_qualifier(qual), namespaces(std::move(namespaces))
, is_undefined(is_undefined), is_function_ptr(is_function_ptr) {}
, type_type(type_type), is_undefined(is_undefined) {}
bool is_type(typedecl_type tt) const { return type_type == tt; }
bool is_unknown() const { return is_type(typedecl_type::unknown); }
bool is_struct() const { return is_type(typedecl_type::struct_); }
bool is_struct_opaque() const { return is_type(typedecl_type::struct_opaque); }
bool is_enum() const { return is_type(typedecl_type::enum_); }
bool is_alias() const { return is_type(typedecl_type::alias); }
bool is_function_ptr() const { return is_type(typedecl_type::function_ptr); }
std::string base_type;
qualifier_def base_qualifier;
std::vector<std::string> namespaces;
bool is_undefined, is_function_ptr;
typedecl_type type_type;
bool is_undefined;
};
inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs)
@ -245,7 +282,7 @@ struct get_qualifier_visitor
return complex.outer.base_qualifier;
}
};
inline bool operator==(type_def const& lhs, type_def const& rhs)
{
return lhs.original_type == rhs.original_type && lhs.c_type == rhs.c_type;
@ -254,9 +291,9 @@ inline bool operator!=(type_def const& lhs, type_def const& rhs)
{
return !(lhs == rhs);
}
type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}, false}, "void", false};
type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}}, "void", false};
inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype)
{
c_type = ::eolian_type_c_type_get(unit, eolian_type, ctype);
@ -267,14 +304,14 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
switch( ::eolian_type_type_get(eolian_type))
{
case EOLIAN_TYPE_VOID:
original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}, false};
original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}};
break;
case EOLIAN_TYPE_REGULAR:
if (!stp)
{
bool is_undefined = false;
Eolian_Typedecl const* decl = eolian_type_typedecl_get(unit, eolian_type);
bool is_function_ptr = decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_FUNCTION_POINTER;
typedecl_type type_type = (decl ? typedecl_type_get(decl) : typedecl_type::unknown);
if(decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_ALIAS)
{
Eolian_Type const* aliased = eolian_typedecl_base_type_get(decl);
@ -289,7 +326,7 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type))
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
namespaces.push_back(&*namespace_iterator);
original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, is_undefined, is_function_ptr}};
original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, type_type, is_undefined}};
}
else
{
@ -320,7 +357,7 @@ inline void type_def::set(Eolian_Expression_Type eolian_exp_type)
switch(eolian_exp_type)
{
case EOLIAN_EXPR_INT:
original_type = attributes::regular_type_def{"int", {{}, {}}, {}, false};
original_type = attributes::regular_type_def{"int", {{}, {}}, {}};
c_type = "int";
break;
default:
@ -351,7 +388,7 @@ struct add_optional_qualifier_visitor
}
};
}
struct parameter_def
{
parameter_direction direction;
@ -369,7 +406,7 @@ struct parameter_def
{
return !(lhs == rhs);
}
parameter_def(parameter_direction direction, type_def type, std::string param_name, Eolian_Unit const* unit)
: direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), unit(unit) {}
parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit)
@ -545,7 +582,7 @@ struct function_def
{
attributes::regular_type_def const* typ =
efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (typ && typ->is_function_ptr)
if (typ && typ->is_function_ptr())
{
char typenam[2] = { 0, };
typenam[0] = template_typename++;
@ -568,7 +605,7 @@ struct function_def
{
attributes::regular_type_def const* typ =
efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (typ && typ->is_function_ptr)
if (typ && typ->is_function_ptr())
{
char typenam[2] = { 0, };
typenam[0] = template_typename++;
@ -652,8 +689,8 @@ struct event_def
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, Eolian_Unit const* unit)
@ -835,7 +872,7 @@ struct klass_def
Eolian_Class const* inherit = &*inherit_iterator;
immediate_inherits.insert({inherit, {}});
}
std::function<void(Eolian_Class const*)> inherit_algo =
std::function<void(Eolian_Class const*)> inherit_algo =
[&] (Eolian_Class const* inherit_klass)
{
for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(inherit_klass))
@ -1100,7 +1137,7 @@ template <>
struct is_tuple<attributes::parameter_def> : std::true_type {};
template <>
struct is_tuple<attributes::event_def> : std::true_type {};
}
} } }

View File

@ -28,7 +28,7 @@ struct parameter_type_generator
attributes::regular_type_def const* typ =
efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (typ && typ->is_function_ptr)
if (typ && typ->is_function_ptr())
return as_generator("F").generate(sink, attributes::unused, context);
return as_generator

View File

@ -0,0 +1,355 @@
using System;
using System.Runtime.InteropServices;
using System.Linq;
using static EinaTestData.BaseData;
namespace TestSuite
{
class TestStructs
{
// Auxiliary function //
private static test.StructSimple structSimpleWithValues()
{
var simple = new test.StructSimple();
simple.Fbyte = (sbyte)-126;
simple.Fubyte = (byte) 254u;
simple.Fchar = '~';
simple.Fshort = (short) -32766;
simple.Fushort = (ushort) 65534u;
simple.Fint = -32766;
simple.Fuint = 65534u;
simple.Flong = -2147483646;
simple.Fulong = 4294967294u;
simple.Fllong = -9223372036854775806;
simple.Fullong = 18446744073709551614u;
simple.Fint8 = (sbyte) -126;
simple.Fuint8 = (byte) 254u;
simple.Fint16 = (short) -32766;
simple.Fuint16 = (ushort) 65534u;
simple.Fint32 = -2147483646;
simple.Fuint32 = 4294967294u;
simple.Fint64 = -9223372036854775806;
simple.Fuint64 = 18446744073709551614u;
simple.Fssize = -2147483646;
simple.Fsize = 4294967294u;
simple.Fintptr = (IntPtr) 0xFE;
simple.Fptrdiff = -2147483646;
simple.Ffloat = -16777216.0f;
simple.Fdouble = -9007199254740992.0;
simple.Fbool = true;
simple.Fvoid_ptr = (IntPtr) 0xFE;
simple.Fenum = test.SampleEnum.V2;
simple.Fstring = "test/string";
simple.Fmstring = "test/mstring";
simple.Fstringshare = "test/stringshare";
return simple;
}
private static void checkStructSimple(test.StructSimple simple)
{
Test.Assert(simple.Fbyte == (sbyte) -126);
Test.Assert(simple.Fubyte == (byte) 254u);
Test.Assert(simple.Fchar == '~');
Test.Assert(simple.Fshort == (short) -32766);
Test.Assert(simple.Fushort == (ushort) 65534u);
Test.Assert(simple.Fint == -32766);
Test.Assert(simple.Fuint == 65534u);
Test.Assert(simple.Flong == -2147483646);
Test.Assert(simple.Fulong == 4294967294u);
Test.Assert(simple.Fllong == -9223372036854775806);
Test.Assert(simple.Fullong == 18446744073709551614u);
Test.Assert(simple.Fint8 == (sbyte) -126);
Test.Assert(simple.Fuint8 == (byte) 254u);
Test.Assert(simple.Fint16 == (short) -32766);
Test.Assert(simple.Fuint16 == (ushort) 65534u);
Test.Assert(simple.Fint32 == -2147483646);
Test.Assert(simple.Fuint32 == 4294967294u);
Test.Assert(simple.Fint64 == -9223372036854775806);
Test.Assert(simple.Fuint64 == 18446744073709551614u);
Test.Assert(simple.Fssize == -2147483646);
Test.Assert(simple.Fsize == 4294967294u);
Test.Assert(simple.Fintptr == (IntPtr) 0xFE);
Test.Assert(simple.Fptrdiff == -2147483646);
Test.Assert(simple.Ffloat == -16777216.0f);
Test.Assert(simple.Fdouble == -9007199254740992.0);
Test.Assert(simple.Fbool == true);
Test.Assert(simple.Fvoid_ptr == (IntPtr) 0xFE);
Test.Assert(simple.Fenum == test.SampleEnum.V2);
Test.Assert(simple.Fstring == "test/string");
Test.Assert(simple.Fmstring == "test/mstring");
Test.Assert(simple.Fstringshare == "test/stringshare");
}
private static void checkZeroedStructSimple(test.StructSimple simple)
{
Test.Assert(simple.Fbyte == 0);
Test.Assert(simple.Fubyte == 0);
Test.Assert(simple.Fchar == '\0');
Test.Assert(simple.Fshort == 0);
Test.Assert(simple.Fushort == 0);
Test.Assert(simple.Fint == 0);
Test.Assert(simple.Fuint == 0);
Test.Assert(simple.Flong == 0);
Test.Assert(simple.Fulong == 0);
Test.Assert(simple.Fllong == 0);
Test.Assert(simple.Fullong == 0);
Test.Assert(simple.Fint8 == 0);
Test.Assert(simple.Fuint8 == 0);
Test.Assert(simple.Fint16 == 0);
Test.Assert(simple.Fuint16 == 0);
Test.Assert(simple.Fint32 == 0);
Test.Assert(simple.Fuint32 == 0);
Test.Assert(simple.Fint64 == 0);
Test.Assert(simple.Fuint64 == 0);
Test.Assert(simple.Fssize == 0);
Test.Assert(simple.Fsize == 0);
Test.Assert(simple.Fintptr == IntPtr.Zero);
Test.Assert(simple.Fptrdiff == 0);
Test.Assert(simple.Ffloat == 0);
Test.Assert(simple.Fdouble == 0);
Test.Assert(simple.Fbool == false);
Test.Assert(simple.Fvoid_ptr == IntPtr.Zero);
Test.Assert(simple.Fenum == test.SampleEnum.V0);
Test.Assert(simple.Fstring == null);
Test.Assert(simple.Fmstring == null);
Test.Assert(simple.Fstringshare == null);
}
private static test.StructComplex structComplexWithValues()
{
var complex = new test.StructComplex();
complex.Farray = new eina.Array<int>();
complex.Farray.Push(0x0);
complex.Farray.Push(0x2A);
complex.Farray.Push(0x42);
complex.Finarray = new eina.Inarray<int>();
complex.Finarray.Push(0x0);
complex.Finarray.Push(0x2A);
complex.Finarray.Push(0x42);
complex.Flist = new eina.List<string>();
complex.Flist.Append("0x0");
complex.Flist.Append("0x2A");
complex.Flist.Append("0x42");
complex.Finlist = new eina.Inlist<int>();
complex.Finlist.Append(0x0);
complex.Finlist.Append(0x2A);
complex.Finlist.Append(0x42);
complex.Fhash = new eina.Hash<string, string>();
complex.Fhash["aa"] = "aaa";
complex.Fhash["bb"] = "bbb";
complex.Fhash["cc"] = "ccc";
complex.Fiterator = complex.Farray.GetIterator();
complex.Fany_value = new eina.Value(eina.ValueType.Double);
complex.Fany_value.Set(-9007199254740992.0);
complex.Fany_value_ptr = new eina.Value(eina.ValueType.String);
complex.Fany_value_ptr.Set("abc");
complex.Fbinbuf = new eina.Binbuf();
complex.Fbinbuf.Append(126);
complex.Fslice.Length = 1;
complex.Fslice.Mem = eina.MemoryNative.Alloc(1);
Marshal.WriteByte(complex.Fslice.Mem, 125);
complex.Fobj = new test.NumberwrapperConcrete();
complex.Fobj.SetNumber(42);
return complex;
}
private static void checkStructComplex(test.StructComplex complex)
{
Test.Assert(complex.Farray.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Finarray.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Flist.ToArray().SequenceEqual(base_seq_str));
Test.Assert(complex.Finlist.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Fhash["aa"] == "aaa");
Test.Assert(complex.Fhash["bb"] == "bbb");
Test.Assert(complex.Fhash["cc"] == "ccc");
int idx = 0;
foreach (int e in complex.Fiterator)
{
Test.Assert(e == base_seq_int[idx]);
++idx;
}
double double_val = 0;
Test.Assert(complex.Fany_value.Get(out double_val));
Test.Assert(double_val == -9007199254740992.0);
string str_val = null;
Test.Assert(complex.Fany_value_ptr.Get(out str_val));
Test.Assert(str_val == "abc");
Test.Assert(complex.Fbinbuf.Length == 1);
Test.Assert(complex.Fbinbuf.GetBytes()[0] == 126);
Test.Assert(complex.Fslice.Length == 1);
Test.Assert(complex.Fslice.GetBytes()[0] == 125);
Test.Assert(complex.Fobj != null);
Test.Assert(complex.Fobj.GetNumber() == 42);
}
private static void checkZeroedStructComplex(test.StructComplex complex)
{
Test.Assert(complex.Farray == null);
Test.Assert(complex.Finarray == null);
Test.Assert(complex.Flist == null);
Test.Assert(complex.Finlist == null);
Test.Assert(complex.Fhash == null);
Test.Assert(complex.Fiterator == null);
Test.Assert(complex.Fany_value == null);
Test.Assert(complex.Fany_value_ptr == null);
Test.Assert(complex.Fbinbuf == null);
Test.Assert(complex.Fslice.Length == 0);
Test.Assert(complex.Fslice.Mem == IntPtr.Zero);
Test.Assert(complex.Fobj == null);
}
// Test cases //
// Default initialization (C# side)
private static void simple_default_instantiation()
{
var simple = new test.StructSimple();
checkZeroedStructSimple(simple);
}
private static void complex_default_instantiation()
{
var complex = new test.StructComplex();
checkZeroedStructComplex(complex);
}
// As parameters
public static void simple_in()
{
var simple = structSimpleWithValues();
test.Testing t = new test.TestingConcrete();
bool r = t.StructSimpleIn(simple);
Test.Assert(r, "Function returned false");
}
// public static void simple_ptr_in()
// {
// var simple = structSimpleWithValues();
// test.Testing t = new test.TestingConcrete();
// bool r = t.struct_simple_ptr_in(simple);
// Test.Assert(r, "Function returned false");
// }
// public static void simple_ptr_in_own()
// {
// var simple = structSimpleWithValues();
// test.Testing t = new test.TestingConcrete();
// bool r = t.struct_simple_ptr_in_own(simple);
// Test.Assert(r, "Function returned false");
// }
public static void simple_out()
{
var simple = new test.StructSimple();
test.Testing t = new test.TestingConcrete();
bool r = t.StructSimpleOut(ref simple);
Test.Assert(r, "Function returned false");
checkStructSimple(simple);
}
// public static void simple_ptr_out()
// {
// }
// public static void simple_ptr_out_own()
// {
// }
public static void simple_return()
{
test.Testing t = new test.TestingConcrete();
var simple = t.StructSimpleReturn();
checkStructSimple(simple);
}
// public static void simple_ptr_return()
// {
// }
// public static void simple_ptr_return_own()
// {
// }
public static void complex_in()
{
var complex = structComplexWithValues();
test.Testing t = new test.TestingConcrete();
bool r = t.StructComplexIn(complex);
Test.Assert(r, "Function returned false");
}
// public static void complex_ptr_in()
// {
// }
// public static void complex_ptr_in_own()
// {
// }
public static void complex_out()
{
var complex = new test.StructComplex();
test.Testing t = new test.TestingConcrete();
bool r = t.StructComplexOut(ref complex);
Test.Assert(r, "Function returned false");
checkStructComplex(complex);
}
// public static void complex_ptr_out()
// {
// }
// public static void complex_ptr_out_own()
// {
// }
public static void complex_return()
{
test.Testing t = new test.TestingConcrete();
var complex = t.StructComplexReturn();
checkStructComplex(complex);
}
// public static void complex_ptr_return()
// {
// }
// public static void complex_ptr_return_own()
// {
// }
}
}

View File

@ -34,6 +34,9 @@
#include "test_numberwrapper.eo.h"
#include "test_testing.eo.h"
#define EQUAL(a, b) ((a) == (b) ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s)", __FILE__, __LINE__, __FUNCTION__), fflush(stderr), 0))
#define STR_EQUAL(a, b) (strcmp((a), (b)) == 0 ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s) '%s' != '%s'", __FILE__, __LINE__, __FUNCTION__, (a), (b)), fflush(stderr), 0))
typedef struct Test_Testing_Data
{
Test_SimpleCb cb;
@ -3123,6 +3126,397 @@ Eina_Error _test_testing_returns_error(EINA_UNUSED Eo *obj, Test_Testing_Data *p
return pd->error_code;
}
// //
// Structs //
// //
// auxiliary functions
static
void struct_simple_with_values(Test_StructSimple *simple)
{
simple->fbyte = -126;
simple->fubyte = 254u;
simple->fchar = '~';
simple->fshort = -32766;
simple->fushort = 65534u;
simple->fint = -32766;
simple->fuint = 65534u;
simple->flong = -2147483646;
simple->fulong = 4294967294u;
simple->fllong = -9223372036854775806;
simple->fullong = 18446744073709551614u;
simple->fint8 = -126;
simple->fuint8 = 254u;
simple->fint16 = -32766;
simple->fuint16 = 65534u;
simple->fint32 = -2147483646;
simple->fuint32 = 4294967294u;
simple->fint64 = -9223372036854775806;
simple->fuint64 = 18446744073709551614u;
simple->fssize = -2147483646;
simple->fsize = 4294967294u;
simple->fintptr = 0xFE;
simple->fptrdiff = -2147483646;
simple->ffloat = -16777216.0;
simple->fdouble = -9007199254740992.0;
simple->fbool = EINA_TRUE;
simple->fvoid_ptr = (void*) 0xFE;
simple->fenum = TEST_SAMPLEENUM_V2;
simple->fstring = "test/string";
simple->fmstring = strdup("test/mstring");
simple->fstringshare = eina_stringshare_add("test/stringshare");
}
static
Eina_Bool check_and_modify_struct_simple(Test_StructSimple *simple)
{
Eina_Bool ret =
EQUAL(simple->fbyte, -126)
&& EQUAL(simple->fubyte, 254u)
&& EQUAL(simple->fchar, '~')
&& EQUAL(simple->fshort, -32766)
&& EQUAL(simple->fushort, 65534u)
&& EQUAL(simple->fint, -32766)
&& EQUAL(simple->fuint, 65534u)
&& EQUAL(simple->flong, -2147483646)
&& EQUAL(simple->fulong, 4294967294u)
&& EQUAL(simple->fllong, -9223372036854775806)
&& EQUAL(simple->fullong, 18446744073709551614u)
&& EQUAL(simple->fint8, -126)
&& EQUAL(simple->fuint8, 254u)
&& EQUAL(simple->fint16, -32766)
&& EQUAL(simple->fuint16, 65534u)
&& EQUAL(simple->fint32, -2147483646)
&& EQUAL(simple->fuint32, 4294967294u)
&& EQUAL(simple->fint64, -9223372036854775806)
&& EQUAL(simple->fuint64, 18446744073709551614u)
&& EQUAL(simple->fssize, -2147483646)
&& EQUAL(simple->fsize, 4294967294u)
&& EQUAL(simple->fintptr, 0xFE)
&& EQUAL(simple->fptrdiff, -2147483646)
&& EQUAL(simple->ffloat, -16777216.0)
&& EQUAL(simple->fdouble, -9007199254740992.0)
&& EQUAL(simple->fbool, EINA_TRUE)
&& EQUAL(simple->fvoid_ptr, (void*) 0xFE)
&& EQUAL(simple->fenum, TEST_SAMPLEENUM_V2)
&& STR_EQUAL(simple->fstring, "test/string")
&& STR_EQUAL(simple->fmstring, "test/mstring")
&& STR_EQUAL(simple->fstringshare, "test/stringshare")
;
if (!ret)
return ret;
simple->fmstring[4] = '-';
return strcmp(simple->fmstring, "test-mstring") == 0;
}
static
Eina_Bool check_zeroed_struct_simple(Test_StructSimple *simple)
{
Eina_Bool ret =
simple->fbyte == 0
&& simple->fubyte == 0
&& simple->fchar == '\0'
&& simple->fshort == 0
&& simple->fushort == 0
&& simple->fint == 0
&& simple->fuint == 0
&& simple->flong == 0
&& simple->fulong == 0
&& simple->fllong == 0
&& simple->fullong == 0
&& simple->fint8 == 0
&& simple->fuint8 == 0
&& simple->fint16 == 0
&& simple->fuint16 == 0
&& simple->fint32 == 0
&& simple->fuint32 == 0
&& simple->fint64 == 0
&& simple->fuint64 == 0
&& simple->fssize == 0
&& simple->fsize == 0
&& simple->fintptr == 0x00
&& simple->fptrdiff == 0
&& simple->ffloat == 0
&& simple->fdouble == 0
&& simple->fbool == EINA_FALSE
&& simple->fvoid_ptr == NULL
&& simple->fenum == TEST_SAMPLEENUM_V0
&& simple->fstring == NULL
&& simple->fmstring == NULL
&& simple->fstringshare == NULL
;
return ret;
}
static
void struct_complex_with_values(Test_StructComplex *complex)
{
complex->farray = eina_array_new(4);
eina_array_push(complex->farray, _new_int(0x0));
eina_array_push(complex->farray, _new_int(0x2A));
eina_array_push(complex->farray, _new_int(0x42));
complex->finarray = eina_inarray_new(sizeof(int), 0);
eina_inarray_push(complex->finarray, _int_ref(0x0));
eina_inarray_push(complex->finarray, _int_ref(0x2A));
eina_inarray_push(complex->finarray, _int_ref(0x42));
complex->flist = eina_list_append(complex->flist, strdup("0x0"));
complex->flist = eina_list_append(complex->flist, strdup("0x2A"));
complex->flist = eina_list_append(complex->flist, strdup("0x42"));
complex->finlist = eina_inlist_append(complex->finlist, _new_inlist_int(0x0));
complex->finlist = eina_inlist_append(complex->finlist, _new_inlist_int(0x2A));
complex->finlist = eina_inlist_append(complex->finlist, _new_inlist_int(0x42));
complex->fhash = eina_hash_string_superfast_new(NULL);
eina_hash_add(complex->fhash, "aa", strdup("aaa"));
eina_hash_add(complex->fhash, "bb", strdup("bbb"));
eina_hash_add(complex->fhash, "cc", strdup("ccc"));
complex->fiterator = eina_array_iterator_new(complex->farray);
eina_value_setup(&complex->fany_value, EINA_VALUE_TYPE_DOUBLE);
eina_value_set(&complex->fany_value, -9007199254740992.0);
complex->fany_value_ptr = eina_value_new(EINA_VALUE_TYPE_STRING);
eina_value_set(complex->fany_value_ptr, "abc");
complex->fbinbuf = eina_binbuf_new();
eina_binbuf_append_char(complex->fbinbuf, 126);
complex->fslice.len = 1;
complex->fslice.mem = malloc(1);
memset((void*)complex->fslice.mem, 125, 1);
complex->fobj = _new_obj(42);
}
static
Eina_Bool check_and_modify_struct_complex(Test_StructComplex *complex)
{
if (!_array_int_equal(complex->farray, base_seq_int, base_seq_int_size))
return EINA_FALSE;
if (!_inarray_int_equal(complex->finarray, base_seq_int, base_seq_int_size))
return EINA_FALSE;
if (!_list_str_equal(complex->flist, base_seq_str, base_seq_str_size))
return EINA_FALSE;
if (!_inlist_int_equal(complex->finlist, base_seq_int, base_seq_int_size))
return EINA_FALSE;
if (!_hash_str_check(complex->fhash, "aa", "aaa")
|| !_hash_str_check(complex->fhash, "bb", "bbb")
|| !_hash_str_check(complex->fhash, "cc", "ccc"))
return EINA_FALSE;
if (!_iterator_int_equal(complex->fiterator, base_seq_int, base_seq_int_size, EINA_FALSE))
return EINA_FALSE;
double double_val = 0;
if (!eina_value_get(&complex->fany_value, &double_val) || double_val != -9007199254740992.0)
return EINA_FALSE;
const char *str_val = NULL;
if (!eina_value_get(complex->fany_value_ptr, &str_val) || strcmp(str_val, "abc") != 0)
return EINA_FALSE;
if (eina_binbuf_length_get(complex->fbinbuf) != 1 || eina_binbuf_string_get(complex->fbinbuf)[0] != 126)
return EINA_FALSE;
if (complex->fslice.len != 1 || *(char*)complex->fslice.mem != 125)
return EINA_FALSE;
if (complex->fobj == NULL || test_numberwrapper_number_get(complex->fobj) != 42)
return EINA_FALSE;
return EINA_TRUE;
}
static
Eina_Bool check_zeroed_struct_complex(Test_StructComplex *complex)
{
Eina_Bool ret =
complex->farray == NULL
&& complex->finarray == NULL
&& complex->flist == NULL
&& complex->finlist == NULL
&& complex->fhash == NULL
&& complex->fiterator == NULL
&& complex->fany_value.type == NULL
&& complex->fany_value.value._guarantee == 0
&& complex->fany_value_ptr == NULL
&& complex->fbinbuf == NULL
&& complex->fslice.len == 0
&& complex->fslice.mem == NULL
&& complex->fobj == NULL
;
return ret;
}
// with simple types
EOLIAN
Eina_Bool _test_testing_struct_simple_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple simple)
{
return check_and_modify_struct_simple(&simple);
}
EOLIAN
Eina_Bool _test_testing_struct_simple_ptr_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
{
(void) simple;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Eina_Bool _test_testing_struct_simple_ptr_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
{
(void) simple;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Eina_Bool _test_testing_struct_simple_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
{
if (!simple)
{
EINA_LOG_ERR("Null struct pointer");
return EINA_FALSE;
}
struct_simple_with_values(simple);
return EINA_TRUE;
}
EOLIAN
Eina_Bool _test_testing_struct_simple_ptr_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
{
(void) simple;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Eina_Bool _test_testing_struct_simple_ptr_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
{
(void) simple;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Test_StructSimple _test_testing_struct_simple_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
Test_StructSimple simple = {0,};
struct_simple_with_values(&simple);
return simple;
}
EOLIAN
Test_StructSimple *_test_testing_struct_simple_ptr_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
EINA_LOG_ERR("Not implemented!");
return NULL;
}
EOLIAN
Test_StructSimple *_test_testing_struct_simple_ptr_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
EINA_LOG_ERR("Not implemented!");
return NULL;
}
// with complex types
EOLIAN
Eina_Bool _test_testing_struct_complex_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex complex)
{
return check_and_modify_struct_complex(&complex);
}
EOLIAN
Eina_Bool _test_testing_struct_complex_ptr_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex *complex)
{
(void) complex;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Eina_Bool _test_testing_struct_complex_ptr_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex *complex)
{
(void) complex;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Eina_Bool _test_testing_struct_complex_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex *complex)
{
if (!complex)
{
EINA_LOG_ERR("Null struct pointer");
return EINA_FALSE;
}
struct_complex_with_values(complex);
return EINA_TRUE;
}
EOLIAN
Eina_Bool _test_testing_struct_complex_ptr_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex **complex)
{
(void) complex;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Eina_Bool _test_testing_struct_complex_ptr_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex **complex)
{
(void) complex;
EINA_LOG_ERR("Not implemented!");
return EINA_FALSE;
}
EOLIAN
Test_StructComplex _test_testing_struct_complex_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
Test_StructComplex complex = {0,};
struct_complex_with_values(&complex);
return complex;
}
EOLIAN
Test_StructComplex* _test_testing_struct_complex_ptr_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
EINA_LOG_ERR("Not implemented!");
return NULL;
}
EOLIAN
Test_StructComplex* _test_testing_struct_complex_ptr_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
EINA_LOG_ERR("Not implemented!");
return NULL;
}
// //
// Class constructor
// //

View File

@ -1,5 +1,79 @@
import eina_types;
enum Test.SampleEnum {
v0,
v1,
v2,
v3,
v4,
}
struct Test.StructSimple
{
fbyte: byte;
fubyte: ubyte;
fchar: char;
fshort: short;
fushort: ushort;
fint: int;
fuint: uint;
flong: long;
fulong: ulong;
fllong: llong;
fullong: ullong;
fint8: int8;
fuint8: uint8;
fint16: int16;
fuint16: uint16;
fint32: int32;
fuint32: uint32;
fint64: int64;
fuint64: uint64;
fssize: ssize;
fsize: size;
fintptr: intptr;
// fuintptr: uintptr; // TODO
fptrdiff: ptrdiff;
ffloat: float;
fdouble: double;
fbool: bool;
fvoid_ptr: void_ptr;
fenum: Test.SampleEnum;
// fboolptr: ptr(bool); // TODO
// fbyteptr: ptr(byte);
// fubyteptr: ptr(ubyte);
// fcharptr: ptr(char);
// fuint8ptr: ptr(uint8);
// fint16ptr: ptr(int16);
// fuint64ptr: ptr(uint64);
// fssizeptr: ptr(ssize);
// fsizeptr: ptr(size);
// fintptrptr: ptr(intptr);
// fptrdiffptr: ptr(ptrdiff);
// ffloatptr: ptr(float);
// fdoubleptr: ptr(double);
// fvoid_ptrptr: ptr(void_ptr);
// fenumptr: ptr(Test.SampleEnum);
fstring: string;
fmstring: mstring;
fstringshare: stringshare;
}
struct Test.StructComplex {
farray: array<ptr(int)>;
finarray: inarray<int>;
flist: list<string>;
finlist: inlist<ptr(int)>;
fhash: hash<string, string>;
fiterator: iterator<ptr(int)>;
fany_value: any_value;
fany_value_ptr: any_value_ptr;
fbinbuf: ptr(Eina.Binbuf);
fslice: Eina.Slice;
// fslice: ptr(Eina.Slice); // TODO
fobj: Test.Numberwrapper;
}
function Test.SimpleCb {
params {
a: int;
@ -1238,6 +1312,116 @@ class Test.Testing (Efl.Object) {
@out value: any_value;
}
}
/* Structs */
struct_simple_in {
params {
@in simple: Test.StructSimple;
}
return: bool;
}
// struct_simple_ptr_in {
// params {
// @in simple: ptr(Test.StructSimple);
// }
// return: bool;
// }
//
// struct_simple_ptr_in_own {
// params {
// @in simple: ptr(Test.StructSimple) @owned;
// }
// return: bool;
// }
struct_simple_out {
params {
@out simple: Test.StructSimple;
}
return: bool;
}
// struct_simple_ptr_out {
// params {
// @out simple: ptr(Test.StructSimple);
// }
// return: bool;
// }
//
// struct_simple_ptr_out_own {
// params {
// @out simple: ptr(Test.StructSimple) @owned;
// }
// return: bool;
// }
struct_simple_return {
return: Test.StructSimple;
}
// struct_simple_ptr_return {
// return: ptr(Test.StructSimple);
// }
//
// struct_simple_ptr_return_own {
// return: ptr(Test.StructSimple) @owned;
// }
struct_complex_in {
params {
@in complex: Test.StructComplex;
}
return: bool;
}
// struct_complex_ptr_in {
// params {
// @in complex: ptr(Test.StructComplex);
// }
// return: bool;
// }
//
// struct_complex_ptr_in_own {
// params {
// @in complex: ptr(Test.StructComplex) @owned;
// }
// return: bool;
// }
struct_complex_out {
params {
@out complex: Test.StructComplex;
}
return: bool;
}
// struct_complex_ptr_out {
// params {
// @out complex: ptr(Test.StructComplex);
// }
// return: bool;
// }
//
// struct_complex_ptr_out_own {
// params {
// @out complex: ptr(Test.StructComplex) @owned;
// }
// return: bool;
// }
struct_complex_return {
return: Test.StructComplex;
}
// struct_complex_ptr_return {
// return: ptr(Test.StructComplex);
// }
//
// struct_complex_ptr_return_own {
// return: ptr(Test.StructComplex) @owned;
// }
}
implements {
class.constructor;