From df0a3d8cc367289950ee2f988c000e6e5f1afb67 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Wed, 1 Jun 2022 16:20:29 -0400 Subject: [PATCH 1/8] Initial implementation --- src/callbacks.rs | 6 ++++++ src/ir/function.rs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/callbacks.rs b/src/callbacks.rs index 9b34544947..b8bdefb399 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -31,6 +31,12 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe { MacroParsingBehavior::Default } + /// This function will run for every function. The returned value determines the name visible + /// in the bindings. + fn link_name_override(&self, _function_name: &str) -> Option { + None + } + /// The integer kind an integer macro should have, given a name and the /// value of that macro, or `None` if you want the default to be chosen. fn int_macro(&self, _name: &str, _value: i64) -> Option { diff --git a/src/ir/function.rs b/src/ir/function.rs index e8e2c2dfed..5dc50d6ac3 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -635,6 +635,12 @@ impl ClangSubItemParser for Function { // but seems easy enough to handle it here. name.push_str("_destructor"); } + if let Some(callbacks) = context.parse_callbacks() { + if let Some(nm) = callbacks.link_name_override(&name) { + name = nm; + } + } + assert!(!name.is_empty(), "Empty function name."); let mangled_name = cursor_mangling(context, &cursor); let comment = cursor.raw_comment(); From 046e73e31b47e4378f988937bfde2a5733e00bbb Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Thu, 2 Jun 2022 11:04:53 -0400 Subject: [PATCH 2/8] Add remove-function-prefix option; Add test --- src/options.rs | 39 +++++++++++++++++++ .../tests/issue-1375-prefixed-functions.rs | 11 ++++++ tests/headers/issue-1375-prefixed-functions.h | 5 +++ tests/parse_callbacks/mod.rs | 11 +++++- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/expectations/tests/issue-1375-prefixed-functions.rs create mode 100644 tests/headers/issue-1375-prefixed-functions.h diff --git a/src/options.rs b/src/options.rs index 081aad61da..d872cc63d5 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use bindgen::{ builder, AliasVariation, Builder, CodegenConfig, EnumVariation, MacroTypeVariation, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, @@ -8,6 +9,34 @@ use std::fs::File; use std::io::{self, stderr, Error, ErrorKind, Write}; use std::path::PathBuf; use std::str::FromStr; +use bindgen::callbacks::ParseCallbacks; + +#[derive(Debug)] +pub struct LinkNameOverrideParseCallback { + pub remove_function_prefix: Option, +} + +impl LinkNameOverrideParseCallback { + pub fn new(prefix: &str) -> Self { + LinkNameOverrideParseCallback { + remove_function_prefix: Some(prefix.to_string()), + } + } +} + +impl ParseCallbacks for LinkNameOverrideParseCallback { + fn link_name_override( + &self, + function_name: &str, + ) -> Option { + if let Some(prefix) = &self.remove_function_prefix { + if function_name.starts_with(prefix) { + return Some(function_name[prefix.len()..].to_string()); + } + } + None + } +} /// Construct a new [`Builder`](./struct.Builder.html) from command line flags. pub fn builder_from_flags( @@ -545,6 +574,11 @@ where Arg::new("vtable-generation") .long("vtable-generation") .help("Enables generation of vtable functions."), + Arg::new("remove-function-prefix") + .long("remove-function-prefix") + .multiple_occurrences(true) + .takes_value(true) + .help("Remove prefix when generating Rust function name.") ]) // .args() .get_matches_from(args); @@ -1015,6 +1049,11 @@ where builder = builder.vtable_generation(true); } + if let Some(prefix) = matches.value_of("remove-function-prefix") { + let lnopc = LinkNameOverrideParseCallback::new(prefix); + builder = builder.parse_callbacks(Box::new(lnopc)); + } + let verbose = matches.is_present("verbose"); Ok((builder, output, verbose)) diff --git a/tests/expectations/tests/issue-1375-prefixed-functions.rs b/tests/expectations/tests/issue-1375-prefixed-functions.rs new file mode 100644 index 0000000000..835b75790d --- /dev/null +++ b/tests/expectations/tests/issue-1375-prefixed-functions.rs @@ -0,0 +1,11 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +extern "C" { + #[link_name = "\u{1}my_custom_prefix_function_name"] + pub fn function_name(x: ::std::os::raw::c_int); +} diff --git a/tests/headers/issue-1375-prefixed-functions.h b/tests/headers/issue-1375-prefixed-functions.h new file mode 100644 index 0000000000..8fb005f989 --- /dev/null +++ b/tests/headers/issue-1375-prefixed-functions.h @@ -0,0 +1,5 @@ +// bindgen-flags: --remove-function-prefix my_custom_prefix_ +// bindgen-parse-callbacks: remove-function-prefix-my_custom_prefix_ + +void my_custom_prefix_function_name(const int x); + diff --git a/tests/parse_callbacks/mod.rs b/tests/parse_callbacks/mod.rs index b94b54de0b..4cec46f2b5 100644 --- a/tests/parse_callbacks/mod.rs +++ b/tests/parse_callbacks/mod.rs @@ -1,4 +1,5 @@ use bindgen::callbacks::*; +use crate::options::LinkNameOverrideParseCallback; #[derive(Debug)] struct EnumVariantRename; @@ -36,7 +37,15 @@ pub fn lookup(cb: &str) -> Box { "enum-variant-rename" => Box::new(EnumVariantRename), "blocklisted-type-implements-trait" => { Box::new(BlocklistedTypeImplementsTrait) + }, + call_back => { + if call_back.starts_with("remove-function-prefix-") { + let prefix = call_back.split("remove-function-prefix-").last().to_owned(); + let lnopc = LinkNameOverrideParseCallback::new(prefix.unwrap()); + Box::new(lnopc) + } else { + panic!("Couldn't find name ParseCallbacks: {}", cb) + } } - _ => panic!("Couldn't find name ParseCallbacks: {}", cb), } } From 0fdd964ab37f81a2fa8be5c485bb57bc5e126ce2 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Thu, 2 Jun 2022 12:43:59 -0400 Subject: [PATCH 3/8] Fix formatting --- src/options.rs | 9 +++------ tests/parse_callbacks/mod.rs | 9 ++++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/options.rs b/src/options.rs index d872cc63d5..3b19795f95 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,15 +1,15 @@ -use std::fmt::Debug; +use bindgen::callbacks::ParseCallbacks; use bindgen::{ builder, AliasVariation, Builder, CodegenConfig, EnumVariation, MacroTypeVariation, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS, }; use clap::{App, Arg}; +use std::fmt::Debug; use std::fs::File; use std::io::{self, stderr, Error, ErrorKind, Write}; use std::path::PathBuf; use std::str::FromStr; -use bindgen::callbacks::ParseCallbacks; #[derive(Debug)] pub struct LinkNameOverrideParseCallback { @@ -25,10 +25,7 @@ impl LinkNameOverrideParseCallback { } impl ParseCallbacks for LinkNameOverrideParseCallback { - fn link_name_override( - &self, - function_name: &str, - ) -> Option { + fn link_name_override(&self, function_name: &str) -> Option { if let Some(prefix) = &self.remove_function_prefix { if function_name.starts_with(prefix) { return Some(function_name[prefix.len()..].to_string()); diff --git a/tests/parse_callbacks/mod.rs b/tests/parse_callbacks/mod.rs index 4cec46f2b5..8bd21de64f 100644 --- a/tests/parse_callbacks/mod.rs +++ b/tests/parse_callbacks/mod.rs @@ -1,5 +1,5 @@ -use bindgen::callbacks::*; use crate::options::LinkNameOverrideParseCallback; +use bindgen::callbacks::*; #[derive(Debug)] struct EnumVariantRename; @@ -37,10 +37,13 @@ pub fn lookup(cb: &str) -> Box { "enum-variant-rename" => Box::new(EnumVariantRename), "blocklisted-type-implements-trait" => { Box::new(BlocklistedTypeImplementsTrait) - }, + } call_back => { if call_back.starts_with("remove-function-prefix-") { - let prefix = call_back.split("remove-function-prefix-").last().to_owned(); + let prefix = call_back + .split("remove-function-prefix-") + .last() + .to_owned(); let lnopc = LinkNameOverrideParseCallback::new(prefix.unwrap()); Box::new(lnopc) } else { From 98a0d71ffec542142a90b399e4e18bfd2c7d6726 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Mon, 6 Jun 2022 09:30:05 -0400 Subject: [PATCH 4/8] Name callback: generated_name_override --- src/callbacks.rs | 2 +- src/ir/function.rs | 2 +- src/options.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callbacks.rs b/src/callbacks.rs index b8bdefb399..d0eb466734 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -33,7 +33,7 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe { /// This function will run for every function. The returned value determines the name visible /// in the bindings. - fn link_name_override(&self, _function_name: &str) -> Option { + fn generated_name_override(&self, _function_name: &str) -> Option { None } diff --git a/src/ir/function.rs b/src/ir/function.rs index 5dc50d6ac3..288c049bf0 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -636,7 +636,7 @@ impl ClangSubItemParser for Function { name.push_str("_destructor"); } if let Some(callbacks) = context.parse_callbacks() { - if let Some(nm) = callbacks.link_name_override(&name) { + if let Some(nm) = callbacks.generated_name_override(&name) { name = nm; } } diff --git a/src/options.rs b/src/options.rs index f4c59e0820..7bf87a5127 100644 --- a/src/options.rs +++ b/src/options.rs @@ -25,7 +25,7 @@ impl LinkNameOverrideParseCallback { } impl ParseCallbacks for LinkNameOverrideParseCallback { - fn link_name_override(&self, function_name: &str) -> Option { + fn generated_name_override(&self, function_name: &str) -> Option { if let Some(prefix) = &self.remove_function_prefix { if function_name.starts_with(prefix) { return Some(function_name[prefix.len()..].to_string()); From 19bd399f6aceb60b0e4091b0d82bc66960bfe4d1 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Mon, 6 Jun 2022 09:41:16 -0400 Subject: [PATCH 5/8] No --remove-function-prefix flag --- src/options.rs | 36 ------------------- tests/headers/issue-1375-prefixed-functions.h | 1 - tests/parse_callbacks/mod.rs | 27 ++++++++++++-- 3 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/options.rs b/src/options.rs index 7bf87a5127..6f9fd9caba 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,40 +1,14 @@ -use bindgen::callbacks::ParseCallbacks; use bindgen::{ builder, AliasVariation, Builder, CodegenConfig, EnumVariation, MacroTypeVariation, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS, }; use clap::{App, Arg}; -use std::fmt::Debug; use std::fs::File; use std::io::{self, stderr, Error, ErrorKind, Write}; use std::path::PathBuf; use std::str::FromStr; -#[derive(Debug)] -pub struct LinkNameOverrideParseCallback { - pub remove_function_prefix: Option, -} - -impl LinkNameOverrideParseCallback { - pub fn new(prefix: &str) -> Self { - LinkNameOverrideParseCallback { - remove_function_prefix: Some(prefix.to_string()), - } - } -} - -impl ParseCallbacks for LinkNameOverrideParseCallback { - fn generated_name_override(&self, function_name: &str) -> Option { - if let Some(prefix) = &self.remove_function_prefix { - if function_name.starts_with(prefix) { - return Some(function_name[prefix.len()..].to_string()); - } - } - None - } -} - /// Construct a new [`Builder`](./struct.Builder.html) from command line flags. pub fn builder_from_flags( args: I, @@ -571,11 +545,6 @@ where Arg::new("vtable-generation") .long("vtable-generation") .help("Enables generation of vtable functions."), - Arg::new("remove-function-prefix") - .long("remove-function-prefix") - .multiple_occurrences(true) - .takes_value(true) - .help("Remove prefix when generating Rust function name."), Arg::new("V") .long("version") .help("Prints the version, and exits"), @@ -1061,11 +1030,6 @@ where builder = builder.vtable_generation(true); } - if let Some(prefix) = matches.value_of("remove-function-prefix") { - let lnopc = LinkNameOverrideParseCallback::new(prefix); - builder = builder.parse_callbacks(Box::new(lnopc)); - } - let verbose = matches.is_present("verbose"); Ok((builder, output, verbose)) diff --git a/tests/headers/issue-1375-prefixed-functions.h b/tests/headers/issue-1375-prefixed-functions.h index 8fb005f989..4264e52d65 100644 --- a/tests/headers/issue-1375-prefixed-functions.h +++ b/tests/headers/issue-1375-prefixed-functions.h @@ -1,4 +1,3 @@ -// bindgen-flags: --remove-function-prefix my_custom_prefix_ // bindgen-parse-callbacks: remove-function-prefix-my_custom_prefix_ void my_custom_prefix_function_name(const int x); diff --git a/tests/parse_callbacks/mod.rs b/tests/parse_callbacks/mod.rs index 8bd21de64f..68d0f015ce 100644 --- a/tests/parse_callbacks/mod.rs +++ b/tests/parse_callbacks/mod.rs @@ -1,6 +1,29 @@ -use crate::options::LinkNameOverrideParseCallback; use bindgen::callbacks::*; +#[derive(Debug)] +pub struct RemoveFunctionPrefixParseCallback { + pub remove_function_prefix: Option, +} + +impl RemoveFunctionPrefixParseCallback { + pub fn new(prefix: &str) -> Self { + RemoveFunctionPrefixParseCallback { + remove_function_prefix: Some(prefix.to_string()), + } + } +} + +impl ParseCallbacks for RemoveFunctionPrefixParseCallback { + fn generated_name_override(&self, function_name: &str) -> Option { + if let Some(prefix) = &self.remove_function_prefix { + if function_name.starts_with(prefix) { + return Some(function_name[prefix.len()..].to_string()); + } + } + None + } +} + #[derive(Debug)] struct EnumVariantRename; @@ -44,7 +67,7 @@ pub fn lookup(cb: &str) -> Box { .split("remove-function-prefix-") .last() .to_owned(); - let lnopc = LinkNameOverrideParseCallback::new(prefix.unwrap()); + let lnopc = RemoveFunctionPrefixParseCallback::new(prefix.unwrap()); Box::new(lnopc) } else { panic!("Couldn't find name ParseCallbacks: {}", cb) From 10402c3cf9a60b4ce84580ccff9d393726e03156 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Mon, 6 Jun 2022 09:45:12 -0400 Subject: [PATCH 6/8] Fix formatting --- tests/parse_callbacks/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/parse_callbacks/mod.rs b/tests/parse_callbacks/mod.rs index 68d0f015ce..2dc35a6d2c 100644 --- a/tests/parse_callbacks/mod.rs +++ b/tests/parse_callbacks/mod.rs @@ -67,7 +67,8 @@ pub fn lookup(cb: &str) -> Box { .split("remove-function-prefix-") .last() .to_owned(); - let lnopc = RemoveFunctionPrefixParseCallback::new(prefix.unwrap()); + let lnopc = + RemoveFunctionPrefixParseCallback::new(prefix.unwrap()); Box::new(lnopc) } else { panic!("Couldn't find name ParseCallbacks: {}", cb) From 2338b13bf058ca5c48adf4f912ee15e4b8591b3a Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Thu, 16 Jun 2022 09:18:49 -0400 Subject: [PATCH 7/8] Bump msrv to 1.56.1 --- .github/workflows/bindgen.yml | 6 +++--- Cargo.toml | 2 ++ README.md | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bindgen.yml b/.github/workflows/bindgen.yml index 0bc7d235d4..3e2234133a 100644 --- a/.github/workflows/bindgen.yml +++ b/.github/workflows/bindgen.yml @@ -46,13 +46,13 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - # MSRV below is documented in README.md, please update that if you + # MSRV below is documented in Cargo.toml and README.md, please update those if you # change this. - toolchain: 1.54.0 + toolchain: 1.56.1 override: true - name: Build with msrv - run: rm Cargo.lock && cargo +1.54.0 build --lib + run: rm Cargo.lock && cargo +1.56.1 build --lib quickchecking: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index b3e4c5016b..f3297d1936 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,8 @@ homepage = "https://rust-lang.github.io/rust-bindgen/" version = "0.60.1" edition = "2018" build = "build.rs" +# If you change this, also update README.md and msrv in .github/workflows/bindgen.yml +rust-version = "1.56.1" include = [ "LICENSE", diff --git a/README.md b/README.md index 4b1194fa2e..3ae5f96733 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ extern "C" { ## MSRV -The minimum supported Rust version is **1.54**. +The minimum supported Rust version is **1.56.1**. No MSRV bump policy has been established yet, so MSRV may increase in any release. From 9df48ddaff3d378c364e4db6699ea1bf1948b7b7 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Thu, 23 Jun 2022 12:25:58 -0400 Subject: [PATCH 8/8] Fix merge mistake --- src/options.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/options.rs b/src/options.rs index 6f9fd9caba..4e1fb93fbe 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1030,7 +1030,5 @@ where builder = builder.vtable_generation(true); } - let verbose = matches.is_present("verbose"); - Ok((builder, output, verbose)) }