config: Allow to output user-defined stuff in the struct body.

This commit is contained in:
Emilio Cobos Álvarez
2019-01-18 22:57:36 +01:00
committed by Ryan Hunt
parent 97348107aa
commit 0a6324f4e6
12 changed files with 290 additions and 24 deletions
+6
View File
@@ -155,6 +155,12 @@ item_types = ["constants", "globals", "enums", "structs", "unions", "typedefs",
[export.rename]
"Struct" = "CAPI_Struct"
# Table of stuff to add to an item body.
[export.body]
"Struct" = """
void cppMethod() const;
"""
[fn]
# An optional prefix to put before every function declaration
prefix = "string"
+12 -17
View File
@@ -8,7 +8,7 @@ use std::fmt;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::Path;
use std::path::Path as StdPath;
use std::str::FromStr;
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
@@ -17,6 +17,7 @@ use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
use toml;
use bindgen::ir::annotation::AnnotationSet;
use bindgen::ir::path::Path;
pub use bindgen::rename::RenameRule;
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
@@ -178,7 +179,7 @@ impl FromStr for ItemType {
deserialize_enum_str!(ItemType);
/// Settings to apply when exporting items.
#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
@@ -190,29 +191,23 @@ 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 append to the body of items.
pub body: HashMap<String, String>,
/// A prefix to add before the name of every item
pub prefix: Option<String>,
/// Types of items to generate.
pub item_types: Vec<ItemType>,
}
impl Default for ExportConfig {
fn default() -> ExportConfig {
ExportConfig {
include: Vec::new(),
exclude: Vec::new(),
rename: HashMap::new(),
prefix: None,
item_types: Vec::new(),
}
}
}
impl ExportConfig {
pub(crate) fn should_generate(&self, item_type: ItemType) -> bool {
self.item_types.is_empty() || self.item_types.contains(&item_type)
}
pub(crate) fn extra_body(&self, path: &Path) -> Option<&str> {
self.body.get(path.name()).map(|s| s.trim_matches('\n'))
}
pub(crate) fn rename(&self, item_name: &mut String) {
if let Some(name) = self.rename.get(item_name) {
*item_name = name.clone();
@@ -610,8 +605,8 @@ impl Default for Config {
}
impl Config {
pub fn from_file<P: AsRef<Path>>(file_name: P) -> Result<Config, String> {
fn read(file_name: &Path) -> io::Result<String> {
pub fn from_file<P: AsRef<StdPath>>(file_name: P) -> Result<Config, String> {
fn read(file_name: &StdPath) -> io::Result<String> {
let file = File::open(file_name)?;
let mut reader = BufReader::new(&file);
let mut contents = String::new();
@@ -627,7 +622,7 @@ impl Config {
}
}
pub fn from_root_or_default<P: AsRef<Path>>(root: P) -> Config {
pub fn from_root_or_default<P: AsRef<StdPath>>(root: P) -> Config {
let c = root.as_ref().join("cbindgen.toml");
if c.exists() {
+7 -7
View File
@@ -790,13 +790,13 @@ impl Source for Enum {
}
}
if config.language == Language::C {
if config.style.generate_typedef() {
out.close_brace(false);
write!(out, " {};", self.export_name);
} else {
out.close_brace(true);
}
if let Some(body) = config.export.extra_body(&self.path) {
out.write_raw_block(body);
}
if config.language == Language::C && config.style.generate_typedef() {
out.close_brace(false);
write!(out, " {};", self.export_name);
} else {
out.close_brace(true);
}
+4
View File
@@ -480,6 +480,10 @@ impl Source for Struct {
}
}
if let Some(body) = config.export.extra_body(&self.path) {
out.write_raw_block(body);
}
if config.language == Language::C && config.style.generate_typedef() {
out.close_brace(false);
write!(out, " {};", self.export_name());
+4
View File
@@ -280,6 +280,10 @@ impl Source for Union {
out.write_vertical_source_list(&vec[..], ListType::Cap(";"));
}
if let Some(body) = config.export.extra_body(&self.path) {
out.write_raw_block(body);
}
if config.language == Language::C && config.style.generate_typedef() {
out.close_brace(false);
write!(out, " {};", self.export_name);
+6
View File
@@ -170,6 +170,12 @@ impl<'a, F: Write> SourceWriter<'a, F> {
write!(self, "{}", text);
}
pub fn write_raw_block(&mut self, block: &str) {
self.new_line();
self.line_started = true;
write!(self, "{}", block);
}
pub fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) {
InnerWriter(self).write_fmt(fmt).unwrap();
}
+50
View File
@@ -0,0 +1,50 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef enum {
Foo1,
Bar1,
Baz1,
} MyCLikeEnum;
typedef struct {
int32_t i;
#ifdef __cplusplus
inline void foo();
#endif
} MyFancyStruct;
typedef enum {
Foo,
Bar,
Baz,
} MyFancyEnum_Tag;
typedef struct {
int32_t _0;
} Bar_Body;
typedef struct {
int32_t _0;
} Baz_Body;
typedef struct {
MyFancyEnum_Tag tag;
union {
Bar_Body bar;
Baz_Body baz;
};
#ifdef __cplusplus
inline void wohoo();
#endif
} MyFancyEnum;
typedef union {
float f;
uint32_t u;
int32_t extra_member; // yolo
} MyUnion;
void root(MyFancyStruct s, MyFancyEnum e, MyCLikeEnum c, MyUnion u);
+53
View File
@@ -0,0 +1,53 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
enum class MyCLikeEnum {
Foo1,
Bar1,
Baz1,
};
struct MyFancyStruct {
int32_t i;
#ifdef __cplusplus
inline void foo();
#endif
};
struct MyFancyEnum {
enum class Tag {
Foo,
Bar,
Baz,
};
struct Bar_Body {
int32_t _0;
};
struct Baz_Body {
int32_t _0;
};
Tag tag;
union {
Bar_Body bar;
Baz_Body baz;
};
#ifdef __cplusplus
inline void wohoo();
#endif
};
union MyUnion {
float f;
uint32_t u;
int32_t extra_member; // yolo
};
extern "C" {
void root(MyFancyStruct s, MyFancyEnum e, MyCLikeEnum c, MyUnion u);
} // extern "C"
+50
View File
@@ -0,0 +1,50 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef enum MyCLikeEnum {
Foo1,
Bar1,
Baz1,
} MyCLikeEnum;
typedef struct MyFancyStruct {
int32_t i;
#ifdef __cplusplus
inline void foo();
#endif
} MyFancyStruct;
typedef enum MyFancyEnum_Tag {
Foo,
Bar,
Baz,
} MyFancyEnum_Tag;
typedef struct Bar_Body {
int32_t _0;
} Bar_Body;
typedef struct Baz_Body {
int32_t _0;
} Baz_Body;
typedef struct MyFancyEnum {
MyFancyEnum_Tag tag;
union {
Bar_Body bar;
Baz_Body baz;
};
#ifdef __cplusplus
inline void wohoo();
#endif
} MyFancyEnum;
typedef union MyUnion {
float f;
uint32_t u;
int32_t extra_member; // yolo
} MyUnion;
void root(MyFancyStruct s, MyFancyEnum e, MyCLikeEnum c, MyUnion u);
+50
View File
@@ -0,0 +1,50 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum MyCLikeEnum {
Foo1,
Bar1,
Baz1,
};
struct MyFancyStruct {
int32_t i;
#ifdef __cplusplus
inline void foo();
#endif
};
enum MyFancyEnum_Tag {
Foo,
Bar,
Baz,
};
struct Bar_Body {
int32_t _0;
};
struct Baz_Body {
int32_t _0;
};
struct MyFancyEnum {
enum MyFancyEnum_Tag tag;
union {
struct Bar_Body bar;
struct Baz_Body baz;
};
#ifdef __cplusplus
inline void wohoo();
#endif
};
union MyUnion {
float f;
uint32_t u;
int32_t extra_member; // yolo
};
void root(struct MyFancyStruct s, struct MyFancyEnum e, enum MyCLikeEnum c, union MyUnion u);
+28
View File
@@ -0,0 +1,28 @@
#[repr(C)]
pub struct MyFancyStruct {
i: i32,
}
#[repr(C)]
pub enum MyFancyEnum {
Foo,
Bar(i32),
Baz(i32),
}
#[repr(C)]
pub enum MyCLikeEnum {
Foo1,
Bar1,
Baz1,
}
#[repr(C)]
pub union MyUnion {
pub f: f32,
pub u: u32,
}
#[no_mangle]
pub extern "C" fn root(s: MyFancyStruct, e: MyFancyEnum, c: MyCLikeEnum, u: MyUnion) {}
+20
View File
@@ -0,0 +1,20 @@
[export.body]
"MyFancyStruct" = """
#ifdef __cplusplus
inline void foo();
#endif
"""
"MyFancyEnum" = """
#ifdef __cplusplus
inline void wohoo();
#endif
"""
"MyCLikeEnum" = """
BogusVariantForSerializationForExample,
"""
"MyUnion" = """
int32_t extra_member; // yolo
"""