cpp_common-0.5.6/.cargo_vcs_info.json0000644000000001121377257563000132450ustar { "git": { "sha1": "65b553eaaa2e9fa7acefe12e25ff47724005d057" } } cpp_common-0.5.6/Cargo.toml0000644000000022031377257563000112460ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "cpp_common" version = "0.5.6" authors = ["Nika Layzell ", "Olivier Goffart "] description = "Implementation details crate for the `cpp` crate" documentation = "https://docs.rs/cpp_common" readme = "../README.md" keywords = ["c", "cxx", "ffi", "compiler", "build-dependencies"] categories = ["development-tools::ffi"] license = "MIT/Apache-2.0" repository = "https://github.com/mystor/rust-cpp" [dependencies.lazy_static] version = "1.0" [dependencies.proc-macro2] version = "1.0" [dependencies.syn] version = "1.0" features = ["full", "extra-traits"] cpp_common-0.5.6/Cargo.toml.orig010064400017520001752000000011161377257547600147560ustar 00000000000000[package] name = "cpp_common" version = "0.5.6" authors = ["Nika Layzell ", "Olivier Goffart "] edition = "2018" description = "Implementation details crate for the `cpp` crate" readme = "../README.md" license = "MIT/Apache-2.0" keywords = ["c", "cxx", "ffi", "compiler", "build-dependencies"] categories = ["development-tools::ffi"] repository = "https://github.com/mystor/rust-cpp" documentation = "https://docs.rs/cpp_common" [dependencies] syn = { version = "1.0", features = ["full", "extra-traits"] } lazy_static = "1.0" proc-macro2 = "1.0" cpp_common-0.5.6/src/lib.rs010064600017520001752000000226231352725671100137640ustar 00000000000000//! Implementation detail for the `cpp` crate. //! //! The purpose of this crate is only to allow sharing code between the //! `cpp_build` and the `cpp_macros` crates. #[macro_use] extern crate syn; extern crate proc_macro2; #[macro_use] extern crate lazy_static; use std::collections::hash_map::DefaultHasher; use std::env; use std::hash::{Hash, Hasher}; use std::path::PathBuf; use proc_macro2::{Span, TokenStream, TokenTree}; use syn::ext::IdentExt; use syn::parse::{Parse, ParseStream, Result}; use syn::{Attribute, Ident, Type}; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const LIB_NAME: &str = "librust_cpp_generated.a"; pub const MSVC_LIB_NAME: &str = "rust_cpp_generated.lib"; pub mod flags { pub const IS_COPY_CONSTRUCTIBLE: u32 = 0; pub const IS_DEFAULT_CONSTRUCTIBLE: u32 = 1; pub const IS_TRIVIALLY_DESTRUCTIBLE: u32 = 2; pub const IS_TRIVIALLY_COPYABLE: u32 = 3; pub const IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE: u32 = 4; } pub mod kw { #![allow(non_camel_case_types)] custom_keyword!(rust); } /// This constant is expected to be a unique string within the compiled binary /// which precedes a definition of the metadata. It begins with /// rustcpp~metadata, which is printable to make it easier to locate when /// looking at a binary dump of the metadata. /// /// NOTE: In the future we may want to use a object file parser and a custom /// section rather than depending on this string being unique. #[rustfmt::skip] pub const STRUCT_METADATA_MAGIC: [u8; 128] = [ b'r', b'u', b's', b't', b'c', b'p', b'p', b'~', b'm', b'e', b't', b'a', b'd', b'a', b't', b'a', 92, 74, 112, 213, 165, 185, 214, 120, 179, 17, 185, 25, 182, 253, 82, 118, 148, 29, 139, 208, 59, 153, 78, 137, 230, 54, 26, 177, 232, 121, 132, 166, 44, 106, 218, 57, 158, 33, 69, 32, 54, 204, 123, 226, 99, 117, 60, 173, 112, 61, 56, 174, 117, 141, 126, 249, 79, 159, 6, 119, 2, 129, 147, 66, 135, 136, 212, 252, 231, 105, 239, 91, 96, 232, 113, 94, 164, 255, 152, 144, 64, 207, 192, 90, 225, 171, 59, 154, 60, 2, 0, 191, 114, 182, 38, 134, 134, 183, 212, 227, 31, 217, 12, 5, 65, 221, 150, 59, 230, 96, 73, 62, ]; lazy_static! { pub static ref OUT_DIR: PathBuf = PathBuf::from(env::var("OUT_DIR").expect( r#" -- rust-cpp fatal error -- The OUT_DIR environment variable was not set. NOTE: rustc must be run by Cargo."# )); pub static ref FILE_HASH: u64 = { let mut hasher = std::collections::hash_map::DefaultHasher::new(); OUT_DIR.hash(&mut hasher); hasher.finish() }; } #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct Capture { pub mutable: bool, pub name: Ident, pub cpp: String, } impl Parse for Capture { /// Parse a single captured variable inside within a `cpp!` macro. /// Example: `mut foo as "int"` fn parse(input: ParseStream) -> Result { Ok(Capture { mutable: input.parse::>()?.is_some(), name: input.call(Ident::parse_any)?, cpp: { input.parse::()?; input.parse::()?.value() }, }) } } #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct ClosureSig { pub captures: Vec, pub ret: Option, pub cpp: String, pub std_body: String, } impl ClosureSig { pub fn name_hash(&self) -> u64 { // XXX: Use a better hasher than the default? let mut hasher = DefaultHasher::new(); self.hash(&mut hasher); hasher.finish() } pub fn extern_name(&self) -> Ident { Ident::new( &format!("__cpp_closure_{}", self.name_hash()), Span::call_site(), ) } } #[derive(Clone, Debug)] pub struct Closure { pub sig: ClosureSig, pub body: TokenTree, pub body_str: String, // with `rust!` macro replaced pub callback_offset: u32, } impl Parse for Closure { /// Parse the inside of a `cpp!` macro when this macro is a closure. /// Example: `unsafe [foo as "int"] -> u32 as "int" { /*... */ } fn parse(input: ParseStream) -> Result { input.parse::>()?; // Capture let capture_content; bracketed!(capture_content in input); let captures = syn::punctuated::Punctuated::::parse_terminated(&capture_content)? .into_iter() .collect(); // Optional return type let (ret, cpp) = if input.peek(Token![->]) { input.parse::]>()?; let t: syn::Type = input.parse()?; input.parse::()?; let s = input.parse::()?.value(); (Some(t), s) } else { (None, "void".to_owned()) }; let body = input.parse::()?; // Need to filter the spaces because there is a difference between // proc_macro2 and proc_macro and the hashes would not match let std_body = body .to_string() .chars() .filter(|x| !x.is_whitespace()) .collect(); Ok(Closure { sig: ClosureSig { captures, ret, cpp, std_body, }, body, body_str: String::new(), callback_offset: 0, }) } } #[derive(Clone, Debug)] pub struct Class { pub name: Ident, pub cpp: String, pub attrs: Vec, pub line: String, // the #line directive } impl Class { pub fn name_hash(&self) -> u64 { let mut hasher = DefaultHasher::new(); self.name.hash(&mut hasher); self.cpp.hash(&mut hasher); hasher.finish() } pub fn derives(&self, i: &str) -> bool { self.attrs.iter().any(|x| { use syn::{Meta, NestedMeta}; x.parse_meta().ok().map_or(false, |m| { if let Meta::List(ref list) = m { list.path.is_ident("derive") && list.nested.iter().any(|y| { if let NestedMeta::Meta(Meta::Path(p)) = y { p.is_ident(i) } else { false } }) } else { false } }) }) } } impl Parse for Class { /// Parse the inside of a `cpp_class!` macro. /// Example: `#[derive(Default)] pub unsafe struct Foobar as "FooBar"` fn parse(input: ParseStream) -> Result { Ok(Class { attrs: input.call(Attribute::parse_outer)?, name: { input.parse::()?; input.parse::()?; input.parse::()?; input.parse()? }, cpp: { input.parse::()?; input.parse::()?.value() }, line: String::new(), }) } } #[allow(clippy::large_enum_variant)] #[derive(Debug)] pub enum Macro { Closure(Closure), Lit(TokenStream), } impl Parse for Macro { ///! Parse the inside of a `cpp!` macro (a literal or a closure) fn parse(input: ParseStream) -> Result { if input.peek(syn::token::Brace) { let content; braced!(content in input); return Ok(Macro::Lit(content.parse()?)); } Ok(Macro::Closure(input.parse::()?)) } } #[derive(Debug)] pub struct RustInvocation { pub begin: Span, pub end: Span, pub id: Ident, pub return_type: Option, pub arguments: Vec<(Ident, String)>, // Vec of name and type } impl Parse for RustInvocation { /// Parse a `rust!` macro something looking like `rust!(ident [foo : bar as "bar"] { /*...*/ })` fn parse(input: ParseStream) -> Result { let rust_token = input.parse::()?; input.parse::()?; let macro_content; let p = parenthesized!(macro_content in input); let r = RustInvocation { begin: rust_token.span, end: p.span, id: macro_content.parse()?, arguments: { let capture_content; bracketed!(capture_content in macro_content); capture_content .parse_terminated::<(Ident, String), Token![,]>( |input: ParseStream| -> Result<(Ident, String)> { let i = input.call(Ident::parse_any)?; input.parse::()?; input.parse::()?; input.parse::()?; let s = input.parse::()?.value(); Ok((i, s)) }, )? .into_iter() .collect() }, return_type: if macro_content.peek(Token![->]) { macro_content.parse::]>()?; macro_content.parse::()?; macro_content.parse::()?; Some(macro_content.parse::()?.value()) } else { None }, }; macro_content.parse::()?; Ok(r) } }