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.
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
<< 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))
concrete,
inherit,
inherit_native,
+ structs,
};
wrapper_kind current_wrapper_kind;
};
--- /dev/null
+#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
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))]";
}},
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))]";
}},
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))]";
}},
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))]";
}},
#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"
}}
};
- 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)
{
#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"
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)
)
return true;
+ auto regular = efl::eina::get<attributes::regular_type_def>(¶m.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)
)
return true;
+ auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
+ if (need_struct_conversion(regular))
+ return true;
+
return false;
}
}
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>(¶m.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 ";
bool operator()(grammar::attributes::regular_type_def const &type) const
{
- return type.is_function_ptr;
+ return type.is_function_ptr();
}
template<typename T>
// 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{}))
{
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
{
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>(¶m.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"
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>(¶m.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(
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>(¶m.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)
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>(¶m.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(
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>(¶m.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)
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")
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>(¶m.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"
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)
{
#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;
-
- for (auto it=struct_.namespaces.begin(); it != struct_.namespaces.end(); it++)
- {
- full_name += *it + ".";
- }
-
- 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";
+ return struct_.cxx_name;
+}
+
+inline std::string binding_struct_internal_name(attributes::struct_def const& struct_)
+{
+ return struct_.cxx_name + "_StructInternal";
+}
+
+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
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;
}
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 {};
}
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> {};
}
} } }
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;
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, [&]
, 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");
}
/efl_libs.cs
+/efl_libs.csv
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;
}
[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>();
descriptions.Add(name, data);
}
- this.pointer = descriptions[name];
+ this.Name = descriptions[name];
+ this.Unfreezable = false;
+ this.Legacy_is = false;
+ this.Restart = false;
}
};
namespace eina {
+[StructLayout(LayoutKind.Sequential)]
public struct Rectangle {
public int x;
public int y;
}
-namespace eina {
-
-public interface File {}
-
-}
-
namespace evas {
/* Copied from Evas_Legacy.h */
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>
namespace attributes {
struct complex_type_def;
-
+
}
namespace attributes {
|| (!(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;
{
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)
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;
{
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);
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);
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
{
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:
}
};
}
-
+
struct parameter_def
{
parameter_direction direction;
{
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)
{
attributes::regular_type_def const* typ =
efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (typ && typ->is_function_ptr)
+ if (typ && typ->is_function_ptr())
{
char typenam[2] = { 0, };
typenam[0] = template_typename++;
{
attributes::regular_type_def const* typ =
efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (typ && typ->is_function_ptr)
+ if (typ && typ->is_function_ptr())
{
char typenam[2] = { 0, };
typenam[0] = template_typename++;
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)
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))
struct is_tuple<attributes::parameter_def> : std::true_type {};
template <>
struct is_tuple<attributes::event_def> : std::true_type {};
-
+
}
} } }
attributes::regular_type_def const* typ =
efl::eina::get<attributes::regular_type_def>(¶m.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
--- /dev/null
+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()
+ // {
+ // }
+}
+
+}
#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;
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
// //
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;
@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;