X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Fmain.rs;h=7d26edce5a4a4bd3bf694300a3dcddadc794b429;hb=51a702cc824ac8c0d280cf695ddaade7142d84fa;hp=918a05a935e0c117d93f3dddfcb92365a178a78a;hpb=27024f00ed3d424219c8ed8e652f6d1a97251e34;p=ldk-c-bindings diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 918a05a..7d26edc 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -388,7 +388,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty ident.mutability.is_some() || ident.subpat.is_some() { unimplemented!(); } - write!(w, ", {}{}: ", if $type_resolver.skip_arg(&*arg.ty, Some(&meth_gen_types)) { "_" } else { "" }, ident.ident).unwrap(); + write!(w, ", mut {}{}: ", if $type_resolver.skip_arg(&*arg.ty, Some(&meth_gen_types)) { "_" } else { "" }, ident.ident).unwrap(); } _ => unimplemented!(), } @@ -966,7 +966,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ writeln!(w, "#[no_mangle]").unwrap(); writeln!(w, "/// Read a {} object from a string", ident).unwrap(); writeln!(w, "pub extern \"C\" fn {}_from_str(s: crate::c_types::Str) -> {} {{", ident, container).unwrap(); - writeln!(w, "\tmatch {}::from_str(s.into()) {{", resolved_path).unwrap(); + writeln!(w, "\tmatch {}::from_str(s.into_str()) {{", resolved_path).unwrap(); writeln!(w, "\t\tOk(r) => {{").unwrap(); let new_var = types.write_to_c_conversion_new_var(w, &format_ident!("r"), &*i.self_ty, Some(&gen_types), false); write!(w, "\t\t\tcrate::c_types::CResultTempl::ok(\n\t\t\t\t").unwrap(); @@ -974,7 +974,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ write!(w, "{}r", if new_var { "local_" } else { "" }).unwrap(); types.write_to_c_conversion_inline_suffix(w, &*i.self_ty, Some(&gen_types), false); writeln!(w, "\n\t\t\t)\n\t\t}},").unwrap(); - writeln!(w, "\t\tErr(e) => crate::c_types::CResultTempl::err(0u8),").unwrap(); + writeln!(w, "\t\tErr(e) => crate::c_types::CResultTempl::err(()),").unwrap(); writeln!(w, "\t}}.into()\n}}").unwrap(); } } else if path_matches_nongeneric(&trait_path.1, &["Display"]) { @@ -1137,9 +1137,8 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type } writeln_docs(w, &e.attrs, ""); - if e.generics.lt_token.is_some() { - unimplemented!(); - } + let mut gen_types = GenericTypes::new(None); + assert!(gen_types.learn_generics(&e.generics, types)); let mut needs_free = false; @@ -1155,21 +1154,31 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type if export_status(&field.attrs) == ExportStatus::TestOnly { continue; } writeln_docs(w, &field.attrs, "\t\t"); write!(w, "\t\t{}: ", field.ident.as_ref().unwrap()).unwrap(); - types.write_c_type(w, &field.ty, None, false); + types.write_c_type(w, &field.ty, Some(&gen_types), false); writeln!(w, ",").unwrap(); } write!(w, "\t}}").unwrap(); } else if let syn::Fields::Unnamed(fields) = &var.fields { - needs_free = true; - write!(w, "(").unwrap(); - for (idx, field) in fields.unnamed.iter().enumerate() { - if export_status(&field.attrs) == ExportStatus::TestOnly { continue; } - types.write_c_type(w, &field.ty, None, false); - if idx != fields.unnamed.len() - 1 { - write!(w, ",").unwrap(); + let mut empty_tuple_variant = false; + if fields.unnamed.len() == 1 { + let mut empty_check = Vec::new(); + types.write_c_type(&mut empty_check, &fields.unnamed[0].ty, Some(&gen_types), false); + if empty_check.is_empty() { + empty_tuple_variant = true; + } + } + if !empty_tuple_variant { + needs_free = true; + write!(w, "(").unwrap(); + for (idx, field) in fields.unnamed.iter().enumerate() { + if export_status(&field.attrs) == ExportStatus::TestOnly { continue; } + types.write_c_type(w, &field.ty, Some(&gen_types), false); + if idx != fields.unnamed.len() - 1 { + write!(w, ",").unwrap(); + } } + write!(w, ")").unwrap(); } - write!(w, ")").unwrap(); } if var.discriminant.is_some() { unimplemented!(); } writeln!(w, ",").unwrap(); @@ -1181,6 +1190,7 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type writeln!(w, "\t#[allow(unused)]\n\tpub(crate) fn {} {{\n\t\tmatch {} {{", $fn_sig, if $to_c { "native" } else { "self" }).unwrap(); for var in e.variants.iter() { write!(w, "\t\t\t{}{}::{} ", if $to_c { "native" } else { "" }, e.ident, var.ident).unwrap(); + let mut empty_tuple_variant = false; if let syn::Fields::Named(fields) = &var.fields { write!(w, "{{").unwrap(); for field in fields.named.iter() { @@ -1189,12 +1199,21 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type } write!(w, "}} ").unwrap(); } else if let syn::Fields::Unnamed(fields) = &var.fields { - write!(w, "(").unwrap(); - for (idx, field) in fields.unnamed.iter().enumerate() { - if export_status(&field.attrs) == ExportStatus::TestOnly { continue; } - write!(w, "{}{}, ", if $ref { "ref " } else { "mut " }, ('a' as u8 + idx as u8) as char).unwrap(); + if fields.unnamed.len() == 1 { + let mut empty_check = Vec::new(); + types.write_c_type(&mut empty_check, &fields.unnamed[0].ty, Some(&gen_types), false); + if empty_check.is_empty() { + empty_tuple_variant = true; + } + } + if !empty_tuple_variant || $to_c { + write!(w, "(").unwrap(); + for (idx, field) in fields.unnamed.iter().enumerate() { + if export_status(&field.attrs) == ExportStatus::TestOnly { continue; } + write!(w, "{}{}, ", if $ref { "ref " } else { "mut " }, ('a' as u8 + idx as u8) as char).unwrap(); + } + write!(w, ") ").unwrap(); } - write!(w, ") ").unwrap(); } write!(w, "=>").unwrap(); @@ -1204,9 +1223,9 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type let mut sink = ::std::io::sink(); let mut out: &mut dyn std::io::Write = if $ref { &mut sink } else { w }; let new_var = if $to_c { - types.write_to_c_conversion_new_var(&mut out, $field_ident, &$field.ty, None, false) + types.write_to_c_conversion_new_var(&mut out, $field_ident, &$field.ty, Some(&gen_types), false) } else { - types.write_from_c_conversion_new_var(&mut out, $field_ident, &$field.ty, None) + types.write_from_c_conversion_new_var(&mut out, $field_ident, &$field.ty, Some(&gen_types)) }; if $ref || new_var { if $ref { @@ -1214,9 +1233,9 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type if new_var { let nonref_ident = format_ident!("{}_nonref", $field_ident); if $to_c { - types.write_to_c_conversion_new_var(w, &nonref_ident, &$field.ty, None, false); + types.write_to_c_conversion_new_var(w, &nonref_ident, &$field.ty, Some(&gen_types), false); } else { - types.write_from_c_conversion_new_var(w, &nonref_ident, &$field.ty, None); + types.write_from_c_conversion_new_var(w, &nonref_ident, &$field.ty, Some(&gen_types)); } write!(w, "\n\t\t\t\t").unwrap(); } @@ -1234,7 +1253,9 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type } else if let syn::Fields::Unnamed(fields) = &var.fields { write!(w, " {{\n\t\t\t\t").unwrap(); for (idx, field) in fields.unnamed.iter().enumerate() { - handle_field_a!(field, &format_ident!("{}", ('a' as u8 + idx as u8) as char)); + if !empty_tuple_variant { + handle_field_a!(field, &format_ident!("{}", ('a' as u8 + idx as u8) as char)); + } } } else { write!(w, " ").unwrap(); } @@ -1244,16 +1265,16 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type ($field: expr, $field_ident: expr) => { { if export_status(&$field.attrs) == ExportStatus::TestOnly { continue; } if $to_c { - types.write_to_c_conversion_inline_prefix(w, &$field.ty, None, false); + types.write_to_c_conversion_inline_prefix(w, &$field.ty, Some(&gen_types), false); } else { - types.write_from_c_conversion_prefix(w, &$field.ty, None); + types.write_from_c_conversion_prefix(w, &$field.ty, Some(&gen_types)); } write!(w, "{}{}", $field_ident, if $ref { "_nonref" } else { "" }).unwrap(); if $to_c { - types.write_to_c_conversion_inline_suffix(w, &$field.ty, None, false); + types.write_to_c_conversion_inline_suffix(w, &$field.ty, Some(&gen_types), false); } else { - types.write_from_c_conversion_suffix(w, &$field.ty, None); + types.write_from_c_conversion_suffix(w, &$field.ty, Some(&gen_types)); } write!(w, ",").unwrap(); } } @@ -1269,12 +1290,14 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type writeln!(w, "\n\t\t\t\t}}").unwrap(); write!(w, "\t\t\t}}").unwrap(); } else if let syn::Fields::Unnamed(fields) = &var.fields { - write!(w, " (").unwrap(); - for (idx, field) in fields.unnamed.iter().enumerate() { - write!(w, "\n\t\t\t\t\t").unwrap(); - handle_field_b!(field, &format_ident!("{}", ('a' as u8 + idx as u8) as char)); + if !empty_tuple_variant || !$to_c { + write!(w, " (").unwrap(); + for (idx, field) in fields.unnamed.iter().enumerate() { + write!(w, "\n\t\t\t\t\t").unwrap(); + handle_field_b!(field, &format_ident!("{}", ('a' as u8 + idx as u8) as char)); + } + writeln!(w, "\n\t\t\t\t)").unwrap(); } - writeln!(w, "\n\t\t\t\t)").unwrap(); write!(w, "\t\t\t}}").unwrap(); } writeln!(w, ",").unwrap(); @@ -1399,6 +1422,7 @@ fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &CrateTypes<'a> writeln!(out, "#![allow(unused_braces)]").unwrap(); // TODO: We need to map deny(missing_docs) in the source crate(s) //writeln!(out, "#![deny(missing_docs)]").unwrap(); + writeln!(out, "pub mod version;").unwrap(); writeln!(out, "pub mod c_types;").unwrap(); writeln!(out, "pub mod bitcoin;").unwrap(); } else {