Skip to content

Commit

Permalink
Add [export.pre_body] to config (#452)
Browse files Browse the repository at this point in the history
  • Loading branch information
ejmahler authored and emilio committed Jan 13, 2020
1 parent b740343 commit 5b227c1
Show file tree
Hide file tree
Showing 15 changed files with 468 additions and 14 deletions.
11 changes: 10 additions & 1 deletion docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,16 @@ renaming_overrides_prefixing = true
"MyType" = "my_cool_type"
"my_function" = "BetterFunctionName"

# Table of things to add to the body of any struct, union, or enum that has the
# Table of things to prepend to the body of any struct, union, or enum that has the
# given name. This can be used to add things like methods which don't change ABI,
# mark fields private, etc
[export.pre_body]
"MyType" = """
MyType() = delete;
private:
"""

# Table of things to append to the body of any struct, union, or enum that has the
# given name. This can be used to add things like methods which don't change ABI.
[export.body]
"MyType" = """
Expand Down
8 changes: 7 additions & 1 deletion src/bindgen/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ pub struct ExportConfig {
pub exclude: Vec<String>,
/// Table of name conversions to apply to item names
pub rename: HashMap<String, String>,
/// Table of raw strings to prepend to the body of items.
pub pre_body: HashMap<String, String>,
/// Table of raw strings to append to the body of items.
pub body: HashMap<String, String>,
/// A prefix to add before the name of every item
Expand All @@ -229,7 +231,11 @@ impl ExportConfig {
self.item_types.is_empty() || self.item_types.contains(&item_type)
}

pub(crate) fn extra_body(&self, path: &Path) -> Option<&str> {
pub(crate) fn pre_body(&self, path: &Path) -> Option<&str> {
self.pre_body.get(path.name()).map(|s| s.trim_matches('\n'))
}

pub(crate) fn post_body(&self, path: &Path) -> Option<&str> {
self.body.get(path.name()).map(|s| s.trim_matches('\n'))
}

Expand Down
20 changes: 19 additions & 1 deletion src/bindgen/ir/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,14 @@ impl Source for Enum {

write!(out, " {}", self.export_name());
out.open_brace();

// Emit the pre_body section, if relevant
// Only do this here if we're writing C++, since the struct that wraps everything is starting here.
// If we're writing C, we aren't wrapping the enum and variant structs definitions, so the actual enum struct willstart down below
if let Some(body) = config.export.pre_body(&self.path) {
out.write_raw_block(body);
out.new_line();
}
}

let enum_name = if let Some(ref tag) = self.tag {
Expand Down Expand Up @@ -642,6 +650,14 @@ impl Source for Enum {
}

out.open_brace();

// Emit the pre_body section, if relevant
// Only do this if we're writing C, since the struct is starting right here.
// For C++, the struct wraps all of the above variant structs too, and we write the pre_body section at the begining of that
if let Some(body) = config.export.pre_body(&self.path) {
out.write_raw_block(body);
out.new_line();
}
}

// C++ allows accessing only common initial sequence of union
Expand Down Expand Up @@ -1008,7 +1024,9 @@ impl Source for Enum {
}
}

if let Some(body) = config.export.extra_body(&self.path) {
// Emit the post_body section, if relevant
if let Some(body) = config.export.post_body(&self.path) {
out.new_line();
out.write_raw_block(body);
}

Expand Down
10 changes: 9 additions & 1 deletion src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,12 @@ impl Source for Struct {

out.open_brace();

// Emit the pre_body section, if relevant
if let Some(body) = config.export.pre_body(&self.path) {
out.write_raw_block(body);
out.new_line();
}

if config.documentation {
out.write_vertical_source_list(&self.fields, ListType::Cap(";"));
} else {
Expand Down Expand Up @@ -600,7 +606,9 @@ impl Source for Struct {
}
}

if let Some(body) = config.export.extra_body(&self.path) {
// Emit the post_body section, if relevant
if let Some(body) = config.export.post_body(&self.path) {
out.new_line();
out.write_raw_block(body);
}

Expand Down
10 changes: 9 additions & 1 deletion src/bindgen/ir/union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ impl Source for Union {

out.open_brace();

// Emit the pre_body section, if relevant
if let Some(body) = config.export.pre_body(&self.path) {
out.write_raw_block(body);
out.new_line();
}

if config.documentation {
out.write_vertical_source_list(&self.fields, ListType::Cap(";"));
} else {
Expand All @@ -310,7 +316,9 @@ impl Source for Union {
out.write_vertical_source_list(&vec[..], ListType::Cap(";"));
}

if let Some(body) = config.export.extra_body(&self.path) {
// Emit the post_body section, if relevant
if let Some(body) = config.export.post_body(&self.path) {
out.new_line();
out.write_raw_block(body);
}

Expand Down
1 change: 0 additions & 1 deletion src/bindgen/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ impl<'a, F: Write> SourceWriter<'a, F> {
}

pub fn write_raw_block(&mut self, block: &str) {
self.new_line();
self.line_started = true;
write!(self, "{}", block);
}
Expand Down
53 changes: 52 additions & 1 deletion tests/expectations/body.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ typedef enum {
Baz1,
} MyCLikeEnum;

typedef enum {
Foo1_Prepended,
Bar1_Prepended,
Baz1_Prepended,
} MyCLikeEnum_Prepended;

typedef struct {
int32_t i;
#ifdef __cplusplus
Expand Down Expand Up @@ -47,4 +53,49 @@ typedef union {
int32_t extra_member; // yolo
} MyUnion;

void root(MyFancyStruct s, MyFancyEnum e, MyCLikeEnum c, MyUnion u);
typedef struct {
#ifdef __cplusplus
inline void prepended_wohoo();
#endif
int32_t i;
} MyFancyStruct_Prepended;

typedef enum {
Foo_Prepended,
Bar_Prepended,
Baz_Prepended,
} MyFancyEnum_Prepended_Tag;

typedef struct {
int32_t _0;
} Bar_Prepended_Body;

typedef struct {
int32_t _0;
} Baz_Prepended_Body;

typedef struct {
#ifdef __cplusplus
inline void wohoo();
#endif
MyFancyEnum_Prepended_Tag tag;
union {
Bar_Prepended_Body bar_prepended;
Baz_Prepended_Body baz_prepended;
};
} MyFancyEnum_Prepended;

typedef union {
int32_t extra_member; // yolo
float f;
uint32_t u;
} MyUnion_Prepended;

void root(MyFancyStruct s,
MyFancyEnum e,
MyCLikeEnum c,
MyUnion u,
MyFancyStruct_Prepended sp,
MyFancyEnum_Prepended ep,
MyCLikeEnum_Prepended cp,
MyUnion_Prepended up);
53 changes: 52 additions & 1 deletion tests/expectations/body.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ typedef enum {
Baz1,
} MyCLikeEnum;

typedef enum {
Foo1_Prepended,
Bar1_Prepended,
Baz1_Prepended,
} MyCLikeEnum_Prepended;

typedef struct {
int32_t i;
#ifdef __cplusplus
Expand Down Expand Up @@ -47,11 +53,56 @@ typedef union {
int32_t extra_member; // yolo
} MyUnion;

typedef struct {
#ifdef __cplusplus
inline void prepended_wohoo();
#endif
int32_t i;
} MyFancyStruct_Prepended;

typedef enum {
Foo_Prepended,
Bar_Prepended,
Baz_Prepended,
} MyFancyEnum_Prepended_Tag;

typedef struct {
int32_t _0;
} Bar_Prepended_Body;

typedef struct {
int32_t _0;
} Baz_Prepended_Body;

typedef struct {
#ifdef __cplusplus
inline void wohoo();
#endif
MyFancyEnum_Prepended_Tag tag;
union {
Bar_Prepended_Body bar_prepended;
Baz_Prepended_Body baz_prepended;
};
} MyFancyEnum_Prepended;

typedef union {
int32_t extra_member; // yolo
float f;
uint32_t u;
} MyUnion_Prepended;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(MyFancyStruct s, MyFancyEnum e, MyCLikeEnum c, MyUnion u);
void root(MyFancyStruct s,
MyFancyEnum e,
MyCLikeEnum c,
MyUnion u,
MyFancyStruct_Prepended sp,
MyFancyEnum_Prepended ep,
MyCLikeEnum_Prepended cp,
MyUnion_Prepended up);

#ifdef __cplusplus
} // extern "C"
Expand Down
53 changes: 52 additions & 1 deletion tests/expectations/body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ enum class MyCLikeEnum {
Baz1,
};

enum class MyCLikeEnum_Prepended {
Foo1_Prepended,
Bar1_Prepended,
Baz1_Prepended,
};

struct MyFancyStruct {
int32_t i;
#ifdef __cplusplus
Expand Down Expand Up @@ -47,8 +53,53 @@ union MyUnion {
int32_t extra_member; // yolo
};

struct MyFancyStruct_Prepended {
#ifdef __cplusplus
inline void prepended_wohoo();
#endif
int32_t i;
};

struct MyFancyEnum_Prepended {
#ifdef __cplusplus
inline void wohoo();
#endif
enum class Tag {
Foo_Prepended,
Bar_Prepended,
Baz_Prepended,
};

struct Bar_Prepended_Body {
int32_t _0;
};

struct Baz_Prepended_Body {
int32_t _0;
};

Tag tag;
union {
Bar_Prepended_Body bar_prepended;
Baz_Prepended_Body baz_prepended;
};
};

union MyUnion_Prepended {
int32_t extra_member; // yolo
float f;
uint32_t u;
};

extern "C" {

void root(MyFancyStruct s, MyFancyEnum e, MyCLikeEnum c, MyUnion u);
void root(MyFancyStruct s,
MyFancyEnum e,
MyCLikeEnum c,
MyUnion u,
MyFancyStruct_Prepended sp,
MyFancyEnum_Prepended ep,
MyCLikeEnum_Prepended cp,
MyUnion_Prepended up);

} // extern "C"
Loading

0 comments on commit 5b227c1

Please sign in to comment.