summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/callbacks.rs6
-rw-r--r--src/ir/function.rs6
-rw-r--r--tests/expectations/tests/issue-1375-prefixed-functions.rs11
-rw-r--r--tests/headers/issue-1375-prefixed-functions.h4
-rw-r--r--tests/parse_callbacks/mod.rs38
5 files changed, 64 insertions, 1 deletions
diff --git a/src/callbacks.rs b/src/callbacks.rs
index 9b345449..d0eb4667 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 generated_name_override(&self, _function_name: &str) -> Option<String> {
+ 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<IntKind> {
diff --git a/src/ir/function.rs b/src/ir/function.rs
index 27192bcf..89905351 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.generated_name_override(&name) {
+ name = nm;
+ }
+ }
+ assert!(!name.is_empty(), "Empty function name.");
let mangled_name = cursor_mangling(context, &cursor);
let comment = cursor.raw_comment();
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 00000000..835b7579
--- /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 00000000..4264e52d
--- /dev/null
+++ b/tests/headers/issue-1375-prefixed-functions.h
@@ -0,0 +1,4 @@
+// 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 b94b54de..2dc35a6d 100644
--- a/tests/parse_callbacks/mod.rs
+++ b/tests/parse_callbacks/mod.rs
@@ -1,6 +1,30 @@
use bindgen::callbacks::*;
#[derive(Debug)]
+pub struct RemoveFunctionPrefixParseCallback {
+ pub remove_function_prefix: Option<String>,
+}
+
+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<String> {
+ 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;
impl ParseCallbacks for EnumVariantRename {
@@ -37,6 +61,18 @@ pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
"blocklisted-type-implements-trait" => {
Box::new(BlocklistedTypeImplementsTrait)
}
- _ => panic!("Couldn't find name ParseCallbacks: {}", cb),
+ call_back => {
+ if call_back.starts_with("remove-function-prefix-") {
+ let prefix = call_back
+ .split("remove-function-prefix-")
+ .last()
+ .to_owned();
+ let lnopc =
+ RemoveFunctionPrefixParseCallback::new(prefix.unwrap());
+ Box::new(lnopc)
+ } else {
+ panic!("Couldn't find name ParseCallbacks: {}", cb)
+ }
+ }
}
}