Cleanup config.rs and switch to toml

This commit is contained in:
Ryan Hunt 2017-04-29 13:58:05 -04:00
parent 934343475b
commit 1ec87b6d56
11 changed files with 195 additions and 180 deletions

View File

@ -12,7 +12,7 @@ clap = "2"
log = "0.3"
serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"
toml = "0.3"
[dependencies.syn]
version = "0.11"

View File

@ -33,7 +33,7 @@ extern crate cbindgen;
use cbindgen::{Config, Library};
fn main() {
let config = Config::from_file("bindconf.json");
let config = Config::from_file("cbindgen.toml");
Library::load("../build-script", &config)
.generate().unwrap()

View File

@ -1,14 +0,0 @@
{
"global": {
"include_version": true
},
"per_item": {
"enum_add_sentinel": false,
"struct_gen_op_eq": false,
"struct_gen_op_neq": false,
"struct_gen_op_lt": false,
"struct_gen_op_lte": false,
"struct_gen_op_gt": false,
"struct_gen_op_gte": false
}
}

View File

@ -3,7 +3,7 @@ extern crate cbindgen;
use cbindgen::{Config, Library};
fn main() {
let config = Config::from_file("bindconf.json");
let config = Config::from_file("cbindgen.toml");
Library::load("../build-script", &config)
.generate().unwrap()

View File

@ -0,0 +1,8 @@
[file]
header = "/* This file is autogenerated with cbindgen. */"
include-version = true
[struct]
derive-op-eq = true
derive-op-lt = true
derive-op-lte = true

View File

@ -12,8 +12,13 @@ pub struct Normal {
y: f32,
}
#[repr(C)]
pub struct Comparable {
x: i32,
}
#[no_mangle]
pub extern "C" fn root(x: *mut Opaque, y: Normal)
pub extern "C" fn root(x: *mut Opaque, y: Normal, z: Comparable)
{
}

View File

@ -1,147 +1,40 @@
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::default::Default;
use serde_json;
use toml;
pub use bindgen::directive::*;
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
#[derive(Debug, Clone, Deserialize)]
pub struct FileConfig {
/// Optional text to output at the beginning of the file
pub header: Option<String>,
/// Optional text to output at the end of the file
pub trailer: Option<String>,
/// Optional text to output at major sections to deter manual editing
pub autogen_warning: Option<String>,
/// Include a comment with the version of cbindgen used to generate the file
pub include_version: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ItemConfig {
/// Optional text to output before each function declaration
pub function_prefix: Option<String>,
/// Optional text to output after each function declaration
pub function_postfix: Option<String>,
/// Whether to add a `Sentinel` value at the end of every enum
/// This is useful in Gecko for IPC serialization
pub enum_add_sentinel: bool,
/// Whether to generate a piecewise equality operator
pub struct_gen_op_eq: bool,
/// Whether to generate a piecewise inequality operator
pub struct_gen_op_neq: bool,
/// Whether to generate a less than operator on structs with one field
pub struct_gen_op_lt: bool,
/// Whether to generate a less than or equal to operator on structs with one field
pub struct_gen_op_lte: bool,
/// Whether to generate a greater than operator on structs with one field
pub struct_gen_op_gt: bool,
/// Whether to generate a greater than or equal to operator on structs with one field
pub struct_gen_op_gte: bool,
}
#[derive(Debug, Clone, Deserialize)]
#[derive(Default, Debug, Clone, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Config {
pub global: FileConfig,
pub per_item: ItemConfig,
}
impl FileConfig {
pub fn default() -> FileConfig {
FileConfig {
header: None,
trailer: None,
autogen_warning: None,
include_version: false,
}
}
}
impl ItemConfig {
pub fn default() -> ItemConfig {
ItemConfig {
function_prefix: None,
function_postfix: None,
enum_add_sentinel: false,
struct_gen_op_eq: false,
struct_gen_op_neq: false,
struct_gen_op_lt: false,
struct_gen_op_lte: false,
struct_gen_op_gt: false,
struct_gen_op_gte: false,
}
}
pub fn function_prefix(&self, directives: &DirectiveSet) -> Option<String> {
match directives.atom("function-prefix") {
Some(x) => x,
None => self.function_prefix.clone(),
}
}
pub fn function_postfix(&self, directives: &DirectiveSet) -> Option<String> {
match directives.atom("function-postfix") {
Some(x) => x,
None => self.function_postfix.clone(),
}
}
pub fn enum_add_sentinel(&self, directives: &DirectiveSet) -> bool {
match directives.bool("enum-add-sentinel") {
Some(x) => x,
None => self.enum_add_sentinel,
}
}
pub fn struct_gen_op_eq(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-eq") {
Some(x) => x,
None => self.struct_gen_op_eq,
}
}
pub fn struct_gen_op_neq(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-neq") {
Some(x) => x,
None => self.struct_gen_op_neq,
}
}
pub fn struct_gen_op_lt(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-lt") {
Some(x) => x,
None => self.struct_gen_op_lt,
}
}
pub fn struct_gen_op_lte(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-lte") {
Some(x) => x,
None => self.struct_gen_op_lte,
}
}
pub fn struct_gen_op_gt(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-gt") {
Some(x) => x,
None => self.struct_gen_op_gt,
}
}
pub fn struct_gen_op_gte(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-gte") {
Some(x) => x,
None => self.struct_gen_op_gte,
}
}
pub file: FileConfig,
#[serde(rename = "fn")]
pub function: FunctionConfig,
#[serde(rename = "struct")]
pub structure: StructConfig,
#[serde(rename = "enum")]
pub enumeration: EnumConfig,
}
impl Config {
pub fn from_default() -> Config {
Config {
global: FileConfig::default(),
per_item: ItemConfig::default(),
pub fn from_file(file_name: &str) -> Config {
fn read(file_name: &str) -> io::Result<String> {
let file = File::open(file_name)?;
let mut reader = BufReader::new(&file);
let mut contents = String::new();
reader.read_to_string(&mut contents)?;
Ok(contents)
}
}
pub fn from_file(file: &str) -> Config {
serde_json::from_reader(&File::open(file).unwrap()).unwrap()
let config_text = read(file_name).expect("couldn't open config file");
toml::from_str(&config_text).expect("couldn't parse config file")
}
pub fn from_webrender() -> Config {
@ -154,31 +47,154 @@ impl Config {
* then run `cbindgen -c wr gfx/webrender_bindings/ gfx/webrender_bindings/webrender_ffi_generated.h` */"###;
Config {
global: FileConfig {
file: FileConfig {
header: Some(String::from(license)),
trailer: None,
autogen_warning: Some(String::from(autogen)),
include_version: true,
include_version: Some(true),
},
per_item: ItemConfig {
function_prefix: Some(String::from("WR_INLINE")),
function_postfix: Some(String::from("WR_FUNC")),
enum_add_sentinel: true,
struct_gen_op_eq: true,
struct_gen_op_neq: false,
struct_gen_op_lt: false,
struct_gen_op_lte: false,
struct_gen_op_gt: false,
struct_gen_op_gte: false,
function: FunctionConfig {
prefix: Some(String::from("WR_INLINE")),
postfix: Some(String::from("WR_FUNC")),
},
structure: StructConfig {
derive_op_eq: Some(true),
derive_op_neq: Some(false),
derive_op_lt: Some(false),
derive_op_lte: Some(false),
derive_op_gt: Some(false),
derive_op_gte: Some(false),
},
enumeration: EnumConfig {
add_sentinel: Some(true),
},
}
}
pub fn load(config: &str) -> Config {
match config {
"default" => Config::from_default(),
"default" => Config::default(),
"wr" => Config::from_webrender(),
file => Config::from_file(file),
}
}
}
#[derive(Default, Debug, Clone, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct FileConfig {
/// Optional text to output at the beginning of the file
pub header: Option<String>,
/// Optional text to output at the end of the file
pub trailer: Option<String>,
/// Optional text to output at major sections to deter manual editing
pub autogen_warning: Option<String>,
/// Include a comment with the version of cbindgen used to generate the file
pub include_version: Option<bool>,
}
#[derive(Default, Debug, Clone, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct FunctionConfig {
/// Optional text to output before each function declaration
pub prefix: Option<String>,
/// Optional text to output after each function declaration
pub postfix: Option<String>,
}
impl FunctionConfig {
pub fn prefix(&self, directives: &DirectiveSet) -> Option<String> {
match directives.atom("function-prefix") {
Some(x) => x,
None => self.prefix.clone(),
}
}
pub fn postfix(&self, directives: &DirectiveSet) -> Option<String> {
match directives.atom("function-postfix") {
Some(x) => x,
None => self.postfix.clone(),
}
}
}
#[derive(Default, Debug, Clone, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct StructConfig {
/// Whether to generate a piecewise equality operator
pub derive_op_eq: Option<bool>,
/// Whether to generate a piecewise inequality operator
pub derive_op_neq: Option<bool>,
/// Whether to generate a less than operator on structs with one field
pub derive_op_lt: Option<bool>,
/// Whether to generate a less than or equal to operator on structs with one field
pub derive_op_lte: Option<bool>,
/// Whether to generate a greater than operator on structs with one field
pub derive_op_gt: Option<bool>,
/// Whether to generate a greater than or equal to operator on structs with one field
pub derive_op_gte: Option<bool>,
}
impl StructConfig {
pub fn derive_op_eq(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-eq") {
Some(x) => x,
None => self.derive_op_eq.unwrap_or(false),
}
}
pub fn derive_op_neq(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-neq") {
Some(x) => x,
None => self.derive_op_neq.unwrap_or(false),
}
}
pub fn derive_op_lt(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-lt") {
Some(x) => x,
None => self.derive_op_lt.unwrap_or(false),
}
}
pub fn derive_op_lte(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-lte") {
Some(x) => x,
None => self.derive_op_lte.unwrap_or(false),
}
}
pub fn derive_op_gt(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-gt") {
Some(x) => x,
None => self.derive_op_gt.unwrap_or(false),
}
}
pub fn derive_op_gte(&self, directives: &DirectiveSet) -> bool {
match directives.bool("struct-gen-op-gte") {
Some(x) => x,
None => self.derive_op_gte.unwrap_or(false),
}
}
}
#[derive(Default, Debug, Clone, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct EnumConfig {
/// Whether to add a `Sentinel` value at the end of every enum
/// This is useful in Gecko for IPC serialization
pub add_sentinel: Option<bool>,
}
impl EnumConfig {
pub fn add_sentinel(&self, directives: &DirectiveSet) -> bool {
match directives.bool("enum-add-sentinel") {
Some(x) => x,
None => self.add_sentinel.unwrap_or(false),
}
}
}

View File

@ -306,7 +306,7 @@ impl Function {
}
pub fn write<F: Write>(&self, config: &Config, out: &mut F) {
if let Some(ref f) = config.per_item.function_prefix(&self.directives) {
if let Some(ref f) = config.function.prefix(&self.directives) {
write!(out, "{} ", f).unwrap();
}
@ -324,7 +324,7 @@ impl Function {
}
write!(out, ")").unwrap();
if let Some(ref f) = config.per_item.function_postfix(&self.directives) {
if let Some(ref f) = config.function.postfix(&self.directives) {
write!(out, "\n{}", f).unwrap();
}
write!(out, ";").unwrap()
@ -416,7 +416,7 @@ impl Struct {
write!(out, "\n").unwrap();
if config.per_item.struct_gen_op_eq(&self.directives) && !self.fields.is_empty() {
if config.structure.derive_op_eq(&self.directives) && !self.fields.is_empty() {
write!(out, "\n").unwrap();
write!(out, " bool operator==(const {}& aOther) const {{\n", self.name).unwrap();
write!(out, " return ").unwrap();
@ -430,7 +430,7 @@ impl Struct {
write!(out, "\n").unwrap();
}
if config.per_item.struct_gen_op_neq(&self.directives) && !self.fields.is_empty() {
if config.structure.derive_op_neq(&self.directives) && !self.fields.is_empty() {
write!(out, "\n").unwrap();
write!(out, " bool operator!=(const {}& aOther) const {{\n", self.name).unwrap();
write!(out, " return ").unwrap();
@ -444,7 +444,7 @@ impl Struct {
write!(out, "\n").unwrap();
}
if config.per_item.struct_gen_op_lt(&self.directives) && self.fields.len() == 1 {
if config.structure.derive_op_lt(&self.directives) && self.fields.len() == 1 {
write!(out, "\n").unwrap();
write!(out, " bool operator<(const {}& aOther) const {{\n", self.name).unwrap();
write!(out, " return ").unwrap();
@ -458,7 +458,7 @@ impl Struct {
write!(out, "\n").unwrap();
}
if config.per_item.struct_gen_op_lte(&self.directives) && self.fields.len() == 1 {
if config.structure.derive_op_lte(&self.directives) && self.fields.len() == 1 {
write!(out, "\n").unwrap();
write!(out, " bool operator<=(const {}& aOther) const {{\n", self.name).unwrap();
write!(out, " return ").unwrap();
@ -472,7 +472,7 @@ impl Struct {
write!(out, "\n").unwrap();
}
if config.per_item.struct_gen_op_gt(&self.directives) && self.fields.len() == 1 {
if config.structure.derive_op_gt(&self.directives) && self.fields.len() == 1 {
write!(out, "\n").unwrap();
write!(out, " bool operator>(const {}& aOther) const {{\n", self.name).unwrap();
write!(out, " return ").unwrap();
@ -486,7 +486,7 @@ impl Struct {
write!(out, "\n").unwrap();
}
if config.per_item.struct_gen_op_gte(&self.directives) && self.fields.len() == 1 {
if config.structure.derive_op_gte(&self.directives) && self.fields.len() == 1 {
write!(out, "\n").unwrap();
write!(out, " bool operator>=(const {}& aOther) const {{\n", self.name).unwrap();
write!(out, " return ").unwrap();
@ -603,7 +603,7 @@ impl Enum {
}
write!(out, " {} = {},", value.0, value.1).unwrap();
}
if config.per_item.enum_add_sentinel(&self.directives) {
if config.enumeration.add_sentinel(&self.directives) {
write!(out, "\n\n Sentinel /* this must be last for serialization purposes. */").unwrap();
}
write!(out, "\n}};").unwrap();

View File

@ -372,13 +372,13 @@ impl<'a> GeneratedLibrary<'a> {
}
pub fn write<F: Write>(&self, out: &mut F) {
if let Some(ref f) = self.config.global.header {
if let Some(ref f) = self.config.file.header {
write!(out, "{}\n", f).unwrap();
}
if self.config.global.include_version {
if self.config.file.include_version.unwrap_or(false) {
write!(out, "\n/* Generated with cbindgen:{} */\n", config::VERSION).unwrap();
}
if let Some(ref f) = self.config.global.autogen_warning {
if let Some(ref f) = self.config.file.autogen_warning {
write!(out, "\n{}\n", f).unwrap();
}
@ -396,7 +396,7 @@ impl<'a> GeneratedLibrary<'a> {
write!(out, "\n").unwrap();
}
if let Some(ref f) = self.config.global.autogen_warning {
if let Some(ref f) = self.config.file.autogen_warning {
write!(out, "\n{}\n", f).unwrap();
}
@ -410,10 +410,10 @@ impl<'a> GeneratedLibrary<'a> {
write!(out, "\n").unwrap();
}
if let Some(ref f) = self.config.global.autogen_warning {
if let Some(ref f) = self.config.file.autogen_warning {
write!(out, "\n{}\n", f).unwrap();
}
if let Some(ref f) = self.config.global.trailer {
if let Some(ref f) = self.config.file.trailer {
write!(out, "\n{}\n", f).unwrap();
}
}

View File

@ -1,10 +1,10 @@
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate syn;
extern crate toml;
mod bindgen;

View File

@ -4,10 +4,10 @@ extern crate clap;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate syn;
extern crate toml;
use clap::{Arg, App};
@ -48,7 +48,7 @@ fn main() {
let config = match matches.value_of("config") {
Some(c) => Config::load(c),
None => Config::from_default(),
None => Config::default(),
};
let built = match Library::load(input, &config).generate() {