}
if all_test { return ExportStatus::TestOnly; }
}
- } else if i == "test" || i == "feature" {
- // If its cfg(feature(...)) we assume its test-only
+ } else if i == "test" {
return ExportStatus::TestOnly;
}
}
let mut res = HashSet::new();
res.insert("crate::c_types::u5".to_owned());
res.insert("crate::c_types::ThirtyTwoBytes".to_owned());
+ res.insert("crate::c_types::SecretKey".to_owned());
res.insert("crate::c_types::PublicKey".to_owned());
res.insert("crate::c_types::Transaction".to_owned());
res.insert("crate::c_types::TxOut".to_owned());
// *************************************************
/// Returns true we if can just skip passing this to C entirely
- fn skip_path(&self, full_path: &str) -> bool {
+ pub fn skip_path(&self, full_path: &str) -> bool {
full_path == "bitcoin::secp256k1::Secp256k1" ||
full_path == "bitcoin::secp256k1::Signing" ||
full_path == "bitcoin::secp256k1::Verification"
"core::convert::Infallible" => Some("crate::c_types::NotConstructable"),
- "bech32::u5" => Some("crate::c_types::u5"),
+ "bitcoin::bech32::u5"|"bech32::u5" => Some("crate::c_types::u5"),
"core::num::NonZeroU8" => Some("u8"),
"bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
"bitcoin::hash_types::Txid"|"bitcoin::hash_types::BlockHash"|"bitcoin_hashes::sha256::Hash"
if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"bitcoin::secp256k1::Message" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if is_ref => Some("*const [u8; 32]"),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"lightning::io::Read" => Some("crate::c_types::u8slice"),
"core::convert::Infallible" => Some("panic!(\"You must never construct a NotConstructable! : "),
- "std::time::Duration"|"core::time::Duration" => Some("std::time::Duration::from_secs("),
+ "std::time::Duration"|"core::time::Duration" => Some("core::time::Duration::from_secs("),
"std::time::SystemTime" => Some("(::std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs("),
- "bech32::u5" => Some(""),
+ "bitcoin::bech32::u5"|"bech32::u5" => Some(""),
"core::num::NonZeroU8" => Some("core::num::NonZeroU8::new("),
"bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
"lightning::ln::PaymentSecret" if !is_ref => Some("::lightning::ln::PaymentSecret("),
"lightning::ln::channelmanager::PaymentId" if !is_ref => Some("::lightning::ln::channelmanager::PaymentId("),
"lightning::ln::channelmanager::PaymentId" if is_ref=> Some("&::lightning::ln::channelmanager::PaymentId( unsafe { *"),
+ "lightning::chain::keysinterface::KeyMaterial" if !is_ref => Some("::lightning::chain::keysinterface::KeyMaterial("),
+ "lightning::chain::keysinterface::KeyMaterial" if is_ref=> Some("&::lightning::chain::keysinterface::KeyMaterial( unsafe { *"),
// List of traits we map (possibly during processing of other files):
"lightning::io::Read" => Some("&mut "),
"std::time::Duration"|"core::time::Duration" => Some(")"),
"std::time::SystemTime" => Some("))"),
- "bech32::u5" => Some(".into()"),
+ "bitcoin::bech32::u5"|"bech32::u5" => Some(".into()"),
"core::num::NonZeroU8" => Some(").expect(\"Value must be non-zero\")"),
"bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
"bitcoin::hash_types::Txid" if is_ref => Some(" }[..]).unwrap()"),
"bitcoin::hash_types::Txid" => Some(".data[..]).unwrap()"),
"bitcoin::hash_types::BlockHash" if !is_ref => Some(".data[..]).unwrap()"),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if !is_ref => Some(".data)"),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if is_ref => Some(" })"),
// List of traits we map (possibly during processing of other files):
"std::time::Duration"|"core::time::Duration" => Some(""),
"std::time::SystemTime" => Some(""),
"std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("),
- "core::fmt::Arguments" => Some("format!(\"{}\", "),
+ "core::fmt::Arguments" => Some("alloc::format!(\"{}\", "),
"core::convert::Infallible" => Some("panic!(\"Cannot construct an Infallible: "),
- "bech32::u5" => Some(""),
+ "bitcoin::bech32::u5"|"bech32::u5" => Some(""),
"bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
=> Some("crate::c_types::PublicKey::from_rust(&"),
"bitcoin::hash_types::Txid"|"bitcoin::hash_types::BlockHash"|"bitcoin_hashes::sha256::Hash"
if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
"bitcoin::secp256k1::Message" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if is_ref => Some("&"),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
"lightning::io::Read" => Some("crate::c_types::u8slice::from_vec(&crate::c_types::reader_to_vec("),
"core::convert::Infallible" => Some("\")"),
- "bech32::u5" => Some(".into()"),
+ "bitcoin::bech32::u5"|"bech32::u5" => Some(".into()"),
"bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
=> Some(")"),
"bitcoin::hash_types::Txid"|"bitcoin::hash_types::BlockHash"|"bitcoin_hashes::sha256::Hash"
if !is_ref => Some(".into_inner() }"),
"bitcoin::secp256k1::Message" if !is_ref => Some(".as_ref().clone() }"),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if is_ref => Some(".0"),
- "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"|"lightning::ln::channelmanager::PaymentId"
+ "lightning::ln::PaymentHash"|"lightning::ln::PaymentPreimage"|"lightning::ln::PaymentSecret"
+ |"lightning::ln::channelmanager::PaymentId"|"lightning::chain::keysinterface::KeyMaterial"
if !is_ref => Some(".0 }"),
"lightning::io::Read" => Some("))"),
/// TODO: We should never need to use this!
fn real_rust_type_mapping<'equiv>(&self, thing: &'equiv str) -> &'equiv str {
match thing {
- "lightning::io::Read" => "std::io::Read",
+ "lightning::io::Read" => "crate::c_types::io::Read",
_ => thing,
}
}
assert!(args.next().is_none());
match inner {
syn::Type::Reference(_) => true,
+ syn::Type::Array(a) => {
+ if let syn::Expr::Lit(l) = &a.len {
+ if let syn::Lit::Int(i) = &l.lit {
+ if i.base10_digits().parse::<usize>().unwrap() >= 32 {
+ let mut buf = Vec::new();
+ self.write_rust_type(&mut buf, generics, &a.elem);
+ let ty = String::from_utf8(buf).unwrap();
+ ty == "u8"
+ } else {
+ // Blindly assume that if we're trying to create an empty value for an
+ // array < 32 entries that all-0s may be a valid state.
+ unimplemented!();
+ }
+ } else { unimplemented!(); }
+ } else { unimplemented!(); }
+ },
syn::Type::Path(p) => {
if let Some(resolved) = self.maybe_resolve_path(&p.path, generics) {
if self.c_type_has_inner_from_path(&resolved) { return true; }
let is_inner_ref = if let Some(syn::Type::Reference(_)) = single_contained { true } else { false };
if is_ref {
return Some(("if ", vec![
- (".is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner(".to_owned(),
+ (".is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner(".to_owned(),
format!("({}{}.unwrap())", var_access, if is_inner_ref { "" } else { ".as_ref()" }))
], ") }", ContainerPrefixLocation::OutsideConv));
} else {
return Some(("if ", vec![
- (".is_none() { std::ptr::null_mut() } else { ".to_owned(), format!("({}.unwrap())", var_access))
+ (".is_none() { core::ptr::null_mut() } else { ".to_owned(), format!("({}.unwrap())", var_access))
], " }", ContainerPrefixLocation::OutsideConv));
}
} else if self.is_primitive(&inner_path) || self.c_type_from_path(&inner_path, false, false).is_none() {
}
}
if let Some(t) = single_contained {
+ if let syn::Type::Tuple(syn::TypeTuple { elems, .. }) = t {
+ assert!(elems.is_empty());
+ let inner_name = self.get_c_mangled_container_type(vec![single_contained.unwrap()], generics, "Option").unwrap();
+ return Some(("if ", vec![
+ (format!(".is_none() {{ {}::None }} else {{ {}::Some /*",
+ inner_name, inner_name), format!(""))
+ ], " */}", ContainerPrefixLocation::PerConv));
+ }
if let syn::Type::Reference(syn::TypeReference { elem, .. }) = t {
if let syn::Type::Slice(_) = &**elem {
return Some(("if ", vec![
syn::Type::Path(p) => {
let resolved = self.resolve_path(&p.path, generics);
if self.crate_types.opaques.get(&resolved).is_some() {
- write!(w, "crate::{} {{ inner: std::ptr::null_mut(), is_owned: true }}", resolved).unwrap();
+ write!(w, "crate::{} {{ inner: core::ptr::null_mut(), is_owned: true }}", resolved).unwrap();
} else {
// Assume its a manually-mapped C type, where we can just define an null() fn
write!(w, "{}::null()", self.c_type_from_path(&resolved, false, false).unwrap()).unwrap();
syn::Type::Slice(_) => {
// Option<[]> always implies that we want to treat len() == 0 differently from
// None, so we always map an Option<[]> into a pointer.
- write!(w, " == std::ptr::null_mut()").unwrap();
+ write!(w, " == core::ptr::null_mut()").unwrap();
EmptyValExpectedTy::ReferenceAsPointer
},
_ => unimplemented!(),
// This may result in some outputs not compiling.
if let syn::Type::Path(p) = &*s.elem {
let resolved = self.resolve_path(&p.path, generics);
- assert!(self.is_primitive(&resolved));
- write!(w, "{}", path_lookup("[u8]", is_ref, ptr_for_ref).unwrap()).unwrap();
+ if self.is_primitive(&resolved) {
+ write!(w, "{}", path_lookup("[u8]", is_ref, ptr_for_ref).unwrap()).unwrap();
+ } else {
+ write!(w, "{}", sliceconv(true, None)).unwrap();
+ }
} else if let syn::Type::Reference(r) = &*s.elem {
if let syn::Type::Path(p) = &*r.elem {
write!(w, "{}", sliceconv(self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)), None)).unwrap();
syn::Type::Slice(s) => {
if let syn::Type::Path(p) = &*s.elem {
let resolved = self.resolve_path(&p.path, generics);
- assert!(self.is_primitive(&resolved));
- let slice_path = format!("[{}]", resolved);
- if let Some((prefix, suffix)) = path_lookup(&slice_path, true) {
- write!(w, "let mut local_{} = {}{}{};", ident, prefix, var, suffix).unwrap();
- true
- } else { false }
+ if self.is_primitive(&resolved) {
+ let slice_path = format!("[{}]", resolved);
+ if let Some((prefix, suffix)) = path_lookup(&slice_path, true) {
+ write!(w, "let mut local_{} = {}{}{};", ident, prefix, var, suffix).unwrap();
+ true
+ } else { false }
+ } else {
+ let tyref = [&*s.elem];
+ if to_c {
+ // If we're converting from a slice to a Vec, assume we can clone the
+ // elements and clone them into a new Vec first. Next we'll walk the
+ // new Vec here and convert them to C types.
+ write!(w, "let mut local_{}_clone = Vec::new(); local_{}_clone.extend_from_slice({}); let mut {} = local_{}_clone; ", ident, ident, ident, ident, ident).unwrap();
+ }
+ is_ref = false;
+ convert_container!("Vec", 1, || tyref.iter().map(|t| generics.resolve_type(*t)));
+ unimplemented!("convert_container should return true as container_lookup should succeed for slices");
+ }
} else if let syn::Type::Reference(ty) = &*s.elem {
let tyref = if from_ownable_ref || !to_c { [&*ty.elem] } else { [&*s.elem] };
is_ref = true;
}
if !self.write_c_type_intern(w, t, generics, false, false, false, false) { return false; }
} else {
- assert!(!is_ref); // We don't currently support outer reference types for non-primitive inners
+ // We don't currently support outer reference types for non-primitive inners,
+ // except for the empty tuple.
+ if let syn::Type::Tuple(t_arg) = t {
+ assert!(t_arg.elems.len() == 0 || !is_ref);
+ } else {
+ assert!(!is_ref);
+ }
if !self.write_c_type_intern(w, t, generics, false, false, false, false) { return false; }
}
}
if !self.is_primitive(&resolved) { return false; }
if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(len), .. }) = &a.len {
if self.c_type_from_path(&format!("[{}; {}]", resolved, len.base10_digits()), is_ref, ptr_for_ref).is_none() { return false; }
- write!(w, "_{}{}", resolved, len.base10_digits()).unwrap();
- write!(mangled_type, "_{}{}", resolved, len.base10_digits()).unwrap();
+ if in_type || args.len() != 1 {
+ write!(w, "_{}{}", resolved, len.base10_digits()).unwrap();
+ write!(mangled_type, "_{}{}", resolved, len.base10_digits()).unwrap();
+ } else {
+ let arrty = format!("[{}; {}]", resolved, len.base10_digits());
+ let realty = self.c_type_from_path(&arrty, is_ref, ptr_for_ref).unwrap_or(&arrty);
+ write!(w, "{}", realty).unwrap();
+ write!(mangled_type, "{}", realty).unwrap();
+ }
} else { return false; }
} else { return false; }
},
if self.is_primitive(&resolved) {
write!(w, "{}::{}slice", Self::container_templ_path(), resolved).unwrap();
true
- } else { false }
+ } else {
+ let mut inner_c_ty = Vec::new();
+ assert!(self.write_c_path_intern(&mut inner_c_ty, &p.path, generics, true, false, ptr_for_ref, with_ref_lifetime));
+ if self.is_clonable(&String::from_utf8(inner_c_ty).unwrap()) {
+ if let Some(id) = p.path.get_ident() {
+ let mangled_container = format!("CVec_{}Z", id);
+ write!(w, "{}::{}", Self::generated_container_path(), mangled_container).unwrap();
+ self.check_create_container(mangled_container, "Vec", vec![&*s.elem], generics, false)
+ } else { false }
+ } else { false }
+ }
} else if let syn::Type::Reference(r) = &*s.elem {
if let syn::Type::Path(p) = &*r.elem {
// Slices with "real types" inside are mapped as the equivalent non-ref Vec