Enable ximgproc module
MODIFY
binding-generator/src/class.rs
binding-generator/src/class.rs
@@ -43,17 +43,17 @@ pub enum Kind {
#[derive(Clone)]
pub struct Class<'tu, 'g> {
entity: Entity<'tu>,
- elaborate_name: Option<String>,
+ custom_fullname: Option<String>,
gen_env: & 'g GeneratorEnv < 'tu >,
}
impl<'tu, 'g> Class<'tu, 'g> {
pub fn new(entity: Entity<'tu>, gen_env: &'g GeneratorEnv<'tu>) -> Self {
- Self { entity, elaborate_name: None, gen_env }
+ Self { entity, custom_fullname: None, gen_env }
}
- pub fn new_ext(entity: Entity<'tu>, elaborate_name: Option<String>, gen_env: &'g GeneratorEnv<'tu>) -> Self {
- Self { entity, elaborate_name, gen_env }
+ pub fn new_ext(entity: Entity<'tu>, custom_fullname: String, gen_env: &'g GeneratorEnv<'tu>) -> Self {
+ Self { entity, custom_fullname: Some(custom_fullname), gen_env }
}
fn kind(&self) -> Kind {
@@ -530,35 +530,24 @@ impl Element for Class<'_, '_> {
}
fn cpp_namespace(&self) -> Cow<str> {
- if self.elaborate_name.is_some() {
- let name = self.cpp_fullname();
- if let Some(idx) = name.rfind("::") {
- name[..idx].to_string().into()
- } else {
- name
- }
+ if self.custom_fullname.is_some() {
+ self.cpp_fullname().namespace().to_string().into()
} else {
DefaultElement::cpp_namespace(self)
}
}
fn cpp_localname(&self) -> Cow<str> {
- if self.elaborate_name.is_some() {
- let name = self.cpp_fullname();
- const SEP: &str = "::";
- if let Some(idx) = name.rfind(SEP) {
- name[idx + SEP.len()..].to_string().into()
- } else {
- name
- }
+ if self.custom_fullname.is_some() {
+ self.cpp_fullname().localname().to_string().into()
} else {
DefaultElement::cpp_localname(self)
}
}
fn cpp_fullname(&self) -> Cow<str> {
- if let Some(elaborate_name) = &self.elaborate_name {
- elaborate_name.into()
+ if let Some(custom_fullname) = &self.custom_fullname {
+ custom_fullname.into()
} else {
DefaultElement::cpp_fullname(self)
}

MODIFY
binding-generator/src/enumeration.rs
binding-generator/src/enumeration.rs
@@ -14,6 +14,7 @@ use crate::{
DefaultElement,
Element,
EntityElement,
+ EntityExt,
GeneratedElement,
get_debug,
StrExt,
@@ -22,16 +23,34 @@ use crate::{
#[derive(Clone)]
pub struct Enum<'tu> {
entity: Entity<'tu>,
+ custom_fullname: Option<String>,
}
impl<'tu> Enum<'tu> {
pub fn new(entity: Entity<'tu>) -> Self {
- Self { entity }
+ Self { entity, custom_fullname: None }
+ }
+
+ pub fn new_ext(entity: Entity<'tu>, custom_fullname: String) -> Self {
+ Self { entity, custom_fullname: Some(custom_fullname) }
+ }
+
+ pub fn as_typedefed(&self) -> Option<Entity> {
+ if self.entity.get_kind() == EntityKind::TypedefDecl {
+ let mut child = None;
+ self.entity.walk_children_while(|c| {
+ child = Some(c);
+ false
+ });
+ Some(child.expect("Invalid anonymous typedefed enum"))
+ } else {
+ None
+ }
}
pub fn consts(&self) -> Vec<Const> {
let mut out = vec![];
- self.entity.visit_children(|const_decl, _| {
+ self.as_typedefed().unwrap_or(self.entity).visit_children(|const_decl, _| {
if const_decl.get_kind() == EntityKind::EnumConstantDecl {
out.push(Const::new(const_decl));
}
@@ -65,12 +84,28 @@ impl Element for Enum<'_> {
}
fn cpp_namespace(&self) -> Cow<str> {
+ if self.custom_fullname.is_some() {
+ self.cpp_fullname().namespace().to_string().into()
+ } else {
DefaultElement::cpp_namespace(self)
}
+ }
fn cpp_localname(&self) -> Cow<str> {
+ if self.custom_fullname.is_some() {
+ self.cpp_fullname().localname().to_string().into()
+ } else {
DefaultElement::cpp_localname(self)
}
+ }
+
+ fn cpp_fullname(&self) -> Cow<str> {
+ if let Some(custom_fullname) = &self.custom_fullname {
+ custom_fullname.into()
+ } else {
+ DefaultElement::cpp_fullname(self)
+ }
+ }
fn rust_module(&self) -> Cow<str> {
DefaultElement::rust_module(self)

MODIFY
binding-generator/src/func.rs
binding-generator/src/func.rs
@@ -720,7 +720,20 @@ impl Element for Func<'_, '_> {
}
for arg in self.arguments() {
out.push('_');
- out += &arg.type_ref().cpp_safe_id();
+ let type_ref = arg.type_ref();
+ let mut safe_id = type_ref.cpp_safe_id();
+ // workaround for duplicate function definition for
+ // cv_ximgproc_ContourFitting_estimateTransformation_const__InputArray_const__InputArray_const__OutputArray_doubleX_bool
+ // it has 2 definitions, with pointer and with reference
+ if type_ref.as_reference().map_or(false, |inner| inner.is_primitive()) {
+ let safe_id = safe_id.to_mut();
+ if let Some((idx, last_char)) = safe_id.char_indices().rev().next() {
+ if last_char == 'X' {
+ safe_id.replace_range(idx..idx + 'X'.len_utf8(), "R");
+ }
+ }
+ }
+ out += &safe_id;
}
out.into()
}

MODIFY
binding-generator/src/generator.rs
binding-generator/src/generator.rs
@@ -30,6 +30,7 @@ use crate::{
get_definition_text,
line_reader,
settings,
+ type_ref::Kind as TypeRefKind,
Typedef,
};
@@ -198,11 +199,13 @@ impl<'tu, V: GeneratorVisitor> OpenCVWalker<'tu, V> {
fn process_enum(visitor: &mut impl GeneratorVisitor, enum_decl: Entity) {
let enm = Enum::new(enum_decl);
if !enm.is_excluded() {
+ if !enm.as_typedefed().is_some() {
for cnst in enm.consts() {
if !cnst.is_excluded() {
visitor.visit_const(cnst);
}
}
+ }
if enm.rust_leafname() != "unnamed" {
visitor.visit_enum(enm);
}
@@ -243,9 +246,19 @@ impl<'tu, V: GeneratorVisitor> OpenCVWalker<'tu, V> {
fn process_typedef(visitor: &mut impl GeneratorVisitor, gen_env: &mut GeneratorEnv<'tu>, typedef_decl: Entity<'tu>) {
let typedef = Typedef::new(typedef_decl, gen_env);
+ let type_ref = typedef.type_ref();
+ match type_ref.kind() {
+ TypeRefKind::Class(..) => {
+ return Self::process_class(visitor, gen_env, typedef_decl);
+ }
+ TypeRefKind::Enum(..) => {
+ return Self::process_enum(visitor, typedef_decl);
+ }
+ _ => {}
+ }
let mut export = gen_env.get_export_config(typedef_decl).is_some()
// we need to have a typedef even if it's not exported for e.g. cv::Size
- || typedef.type_ref().is_data_type();
+ || type_ref.is_data_type();
export = export || {
let underlying_type = typedef.underlying_type_ref();
underlying_type.as_function().is_some()

MODIFY
binding-generator/src/settings.rs
binding-generator/src/settings.rs
@@ -159,7 +159,7 @@ pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| hashmap! {
"cv__InputArray__InputArray_const_MatExprX" => "from_matexpr",
"cv__InputArray__InputArray_const_MatX" => "from_mat",
"cv__InputArray__InputArray_const_UMatX" => "from_umat",
- "cv__InputArray__InputArray_const_doubleX" => "from_f64",
+ "cv__InputArray__InputArray_const_doubleR" => "from_f64",
"cv__InputArray__InputArray_const_vector_Mat_X" => "from_mat_vec",
"cv__InputArray__InputArray_const_vector_UMat_X" => "from_umat_vec",
"cv__InputArray__InputArray_const_vector_bool_X" => "from_bool_vec",
@@ -251,9 +251,9 @@ pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| hashmap! {
"cv_read_const_FileNodeX_KeyPointX_const_KeyPointX" => "+_keypoint",
"cv_read_const_FileNodeX_MatX_const_MatX" => "+_mat",
"cv_read_const_FileNodeX_SparseMatX_const_SparseMatX" => "+_sparsemat",
- "cv_read_const_FileNodeX_doubleX_double" => "+_f64",
- "cv_read_const_FileNodeX_floatX_float" => "+_f32",
- "cv_read_const_FileNodeX_intX_int" => "+_i32",
+ "cv_read_const_FileNodeX_doubleR_double" => "+_f64",
+ "cv_read_const_FileNodeX_floatR_float" => "+_f32",
+ "cv_read_const_FileNodeX_intR_int" => "+_i32",
"cv_read_const_FileNodeX_stringX_const_stringX" => "+_str",
"cv_read_const_FileNodeX_vector_DMatch_X" => "+_dmatch_vec_legacy",
"cv_read_const_FileNodeX_vector_KeyPoint_X" => "+_keypoint_vec_legacy",
@@ -315,8 +315,8 @@ pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| hashmap! {
"cv_dnn_DictValue_get_int_const_int" => "+_i32",
"cv_dnn_Dict_ptr_const_StringX" => "+_mut",
"cv_dnn_Dict_set_cv_String_const_StringX_const_StringX" => "+_str",
- "cv_dnn_Dict_set_double_const_StringX_const_doubleX" => "+_f64",
- "cv_dnn_Dict_set_int64_t_const_StringX_const_int64_tX" => "+_i64",
+ "cv_dnn_Dict_set_double_const_StringX_const_doubleR" => "+_f64",
+ "cv_dnn_Dict_set_int64_t_const_StringX_const_int64_tR" => "+_i64",
"cv_dnn_Layer_finalize_const_vector_Mat_X" => "+_mat",
"cv_dnn_Layer_finalize_const_vector_Mat_X_vector_Mat_X" => "+_mat_to",
"cv_dnn_Layer_forward_vector_MatX_X_vector_Mat_X_vector_Mat_X" => "+_mat",
@@ -325,7 +325,7 @@ pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| hashmap! {
"cv_dnn_Net_forward_const_StringX" => "+_single",
"cv_dnn_Net_forward_const__OutputArrayX_const_StringX" => "+_layer",
"cv_dnn_Net_getMemoryConsumption_const_const_vector_MatShape_X_vector_int_X_vector_size_t_X_vector_size_t_X" => "+_for_layers",
- "cv_dnn_Net_getMemoryConsumption_const_int_const_vector_MatShape_X_size_tX_size_tX" => "+_for_layer",
+ "cv_dnn_Net_getMemoryConsumption_const_int_const_vector_MatShape_X_size_tR_size_tR" => "+_for_layer",
"cv_dnn_blobFromImage_const__InputArrayX_const__OutputArrayX_double_const_SizeX_const_ScalarX_bool_bool_int" => "+_to",
"cv_dnn_blobFromImages_const__InputArrayX_const__OutputArrayX_double_Size_const_ScalarX_bool_bool_int" => "+_to",
"cv_dnn_readNetFromCaffe_const_charX_size_t_const_charX_size_t" => "+_str",

MODIFY
binding-generator/src/string_ext.rs
binding-generator/src/string_ext.rs
@@ -332,6 +332,8 @@ pub trait StrExt {
fn trim_start_idx(&self) -> usize;
fn trim_end_idx(&self) -> usize;
fn strip_str_prefix(&self, prefix: &str) -> Option<&str>;
+ fn localname(&self) -> &str;
+ fn namespace(&self) -> &str;
}
impl StrExt for str {
@@ -442,4 +444,21 @@ impl StrExt for str {
None
}
}
+
+ fn localname(&self) -> &str {
+ const SEP: &str = "::";
+ if let Some(idx) = self.rfind(SEP) {
+ &self[idx + SEP.len()..]
+ } else {
+ self
+ }
+ }
+
+ fn namespace(&self) -> &str {
+ if let Some(idx) = self.rfind("::") {
+ &self[..idx]
+ } else {
+ self
+ }
+ }
}

MODIFY
binding-generator/src/type_ref.rs
binding-generator/src/type_ref.rs
@@ -15,6 +15,7 @@ use crate::{
Class,
DefinitionLocation,
Element,
+ EntityExt,
Enum,
Field,
Function,
@@ -233,7 +234,7 @@ impl<'tu, 'g> TypeRef<'tu, 'g> {
elaborate_name.replace_in_place("const ", "");
if let Some(decl) = self.type_ref.get_declaration() {
if elaborate_name.starts_with("std::") {
- return Kind::Class(Class::new_ext(decl, Some(elaborate_name), self.gen_env))
+ return Kind::Class(Class::new_ext(decl, elaborate_name, self.gen_env))
}
}
}
@@ -282,6 +283,22 @@ impl<'tu, 'g> TypeRef<'tu, 'g> {
Kind::Ignored
}
} else {
+ let mut non_typedef = None;
+ decl.walk_children_while(|child| {
+ match child.get_kind() {
+ EntityKind::StructDecl if child.get_name().is_none() => {
+ non_typedef = Some(Kind::Class(Class::new_ext(child, decl.cpp_fullname().into_owned(), self.gen_env)));
+ }
+ EntityKind::EnumDecl if child.get_name().is_none() => {
+ non_typedef = Some(Kind::Enum(Enum::new_ext(child, decl.cpp_fullname().into_owned())));
+ }
+ _ => {}
+ }
+ false
+ });
+ if let Some(out) = non_typedef {
+ return out;
+ }
Kind::Typedef(Typedef::new(decl, self.gen_env))
}
}

MODIFY
build.rs
build.rs
@@ -918,7 +918,6 @@ fn make_modules(opencv_dir_as_string: &str) -> Result<()> {
"optflow",
"rgbd",
"tracking",
- "ximgproc",
].iter().copied());
let modules: Vec<String> = glob(&format!("{}/*.hpp", opencv_dir_as_string))?

Enable ximgproc module