Skip to content

Commit 203eeec

Browse files
committed
Add rename rule for generated associated constant
In FFI Rust code it is often necessary to use constants instead of enums for compatibility reasons. The most natural thing to do to somewhat preserve grouping is to use associated constants. E.g.: ```rust #[repr(C)] struct Foo {} impl Foo { pub const FLAG1: u32 = 10; pub const FLAG2: u32 = 11; ... ``` For the above, the generated constants would be called Foo_FLAG1 & Foo_FLAG2. Many Linux core C libraries adhere to a slightly different casing, however, where the type prefix is fully upper cased: FOO_FLAG1. Currently, it does not seem possible to generate such constants. This change introduces a new config option to structured types that enables this use case: the struct.rename_associated_constant option expects a rename rule (as other rename related config options) and applies it to the struct base name as used in conjunction with associated constants to form the final name of the constant. Signed-off-by: Daniel Müller <[email protected]>
1 parent bd78bbe commit 203eeec

16 files changed

+183
-1
lines changed

docs.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,12 @@ deprecated_with_notes = "DEPRECATED_STRUCT_WITH_NOTE"
837837
# default: false
838838
# associated_constants_in_body: false
839839

840+
# The rename rule to apply to the struct name used for prefixing associated
841+
# constants.
842+
#
843+
# default: "None"
844+
rename_associated_constant = "None"
845+
840846
# Whether to derive a simple constructor that takes a value for every field.
841847
# default: false
842848
derive_constructor = true

src/bindgen/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ pub struct StructConfig {
493493
/// Whether associated constants should be in the body. Only applicable to
494494
/// non-transparent structs, and in C++-only.
495495
pub associated_constants_in_body: bool,
496+
/// The rename rule to apply to the struct name used for prefixing associated
497+
/// constants
498+
pub rename_associated_constant: RenameRule,
496499
/// The way to annotate this struct as #[must_use].
497500
pub must_use: Option<String>,
498501
/// The way to annotation this function as #[deprecated] without notes

src/bindgen/ir/constant.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::bindgen::ir::{
1818
};
1919
use crate::bindgen::language_backend::LanguageBackend;
2020
use crate::bindgen::library::Library;
21+
use crate::bindgen::rename::{IdentifierType, RenameRule};
2122
use crate::bindgen::writer::SourceWriter;
2223
use crate::bindgen::Bindings;
2324

@@ -666,7 +667,21 @@ impl Constant {
666667
Cow::Borrowed(self.export_name())
667668
} else {
668669
let associated_name = match associated_to_struct {
669-
Some(s) => Cow::Borrowed(s.export_name()),
670+
Some(s) => {
671+
let name = s.export_name();
672+
let rules = s
673+
.annotations
674+
.parse_atom::<RenameRule>("rename-associated-constant");
675+
let rules = rules
676+
.as_ref()
677+
.unwrap_or(&config.structure.rename_associated_constant);
678+
679+
if let Some(r) = rules.not_none() {
680+
r.apply(name, IdentifierType::Type)
681+
} else {
682+
Cow::Borrowed(name)
683+
}
684+
}
670685
None => {
671686
let mut name = self.associated_to.as_ref().unwrap().name().to_owned();
672687
config.export.rename(&mut name);

template.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ rename_fields = "None"
9595
# must_use = "MUST_USE_STRUCT"
9696
# deprecated = "DEPRECATED_STRUCT"
9797
# deprecated_with_note = "DEPRECATED_STRUCT_WITH_NOTE"
98+
rename_associated_constant = "None"
9899
derive_constructor = false
99100
derive_eq = false
100101
derive_neq = false
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
root;
3+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdarg.h>
2+
#include <stdbool.h>
3+
#include <stdint.h>
4+
#include <stdlib.h>
5+
6+
typedef struct {
7+
8+
} Foo;
9+
#define FOO_GA 10
10+
#define FOO_ZO 3.14
11+
12+
void root(Foo x);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <stdarg.h>
2+
#include <stdbool.h>
3+
#include <stdint.h>
4+
#include <stdlib.h>
5+
6+
typedef struct {
7+
8+
} Foo;
9+
#define FOO_GA 10
10+
#define FOO_ZO 3.14
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif // __cplusplus
15+
16+
void root(Foo x);
17+
18+
#ifdef __cplusplus
19+
} // extern "C"
20+
#endif // __cplusplus
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <cstdarg>
2+
#include <cstdint>
3+
#include <cstdlib>
4+
#include <ostream>
5+
#include <new>
6+
7+
struct Foo {
8+
9+
};
10+
constexpr static const int32_t FOO_GA = 10;
11+
constexpr static const float FOO_ZO = 3.14;
12+
13+
extern "C" {
14+
15+
void root(Foo x);
16+
17+
} // extern "C"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
2+
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
3+
cdef extern from *:
4+
ctypedef bint bool
5+
ctypedef struct va_list
6+
7+
cdef extern from *:
8+
9+
ctypedef struct Foo:
10+
pass
11+
const int32_t FOO_GA # = 10
12+
const float FOO_ZO # = 3.14
13+
14+
void root(Foo x);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdarg.h>
2+
#include <stdbool.h>
3+
#include <stdint.h>
4+
#include <stdlib.h>
5+
6+
typedef struct Foo {
7+
8+
} Foo;
9+
#define FOO_GA 10
10+
#define FOO_ZO 3.14
11+
12+
void root(struct Foo x);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <stdarg.h>
2+
#include <stdbool.h>
3+
#include <stdint.h>
4+
#include <stdlib.h>
5+
6+
typedef struct Foo {
7+
8+
} Foo;
9+
#define FOO_GA 10
10+
#define FOO_ZO 3.14
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif // __cplusplus
15+
16+
void root(struct Foo x);
17+
18+
#ifdef __cplusplus
19+
} // extern "C"
20+
#endif // __cplusplus
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdarg.h>
2+
#include <stdbool.h>
3+
#include <stdint.h>
4+
#include <stdlib.h>
5+
6+
struct Foo {
7+
8+
};
9+
#define FOO_GA 10
10+
#define FOO_ZO 3.14
11+
12+
void root(struct Foo x);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <stdarg.h>
2+
#include <stdbool.h>
3+
#include <stdint.h>
4+
#include <stdlib.h>
5+
6+
struct Foo {
7+
8+
};
9+
#define FOO_GA 10
10+
#define FOO_ZO 3.14
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif // __cplusplus
15+
16+
void root(struct Foo x);
17+
18+
#ifdef __cplusplus
19+
} // extern "C"
20+
#endif // __cplusplus
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
2+
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
3+
cdef extern from *:
4+
ctypedef bint bool
5+
ctypedef struct va_list
6+
7+
cdef extern from *:
8+
9+
cdef struct Foo:
10+
pass
11+
const int32_t FOO_GA # = 10
12+
const float FOO_ZO # = 3.14
13+
14+
void root(Foo x);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// cbindgen:rename-associated-constant=UpperCase
2+
#[repr(C)]
3+
struct Foo {}
4+
5+
impl Foo {
6+
pub const GA: i32 = 10;
7+
pub const ZO: f32 = 3.14;
8+
}
9+
10+
#[no_mangle]
11+
pub extern "C" fn root(x: Foo) { }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[struct]
2+
rename_associated_constant = "UpperCase"

0 commit comments

Comments
 (0)