Added test mod_attr project
Added impl of `fmt::Display` for `Cfg` Added `fn matched_defines(…)` for filtering for matches in `[defines]` Changes semantic of `has_defines` from `∀` to `∃` (i.e. all -> one or more) Changed `write_before` to use `matched_defines` Added logging of warning for omitted `#[cfg(…)]`s Added expectations for `mod_attr` test project Renamed function arguments in `mod_attr` test project Rustfmt Introduced `Condition` type to ensure correct API usage of `Cfg` Merged `Condition::Boolean` and `Condition::Named` into `Condition::Define` Removed `DefineConfig` and `MissingDefineBehavior`. (Was getting a bit ahead of myself with these.) Rustfmt
This commit is contained in:
+142
-88
@@ -2,6 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
|
||||
use syn;
|
||||
@@ -9,6 +10,7 @@ use syn;
|
||||
use bindgen::config::Config;
|
||||
use bindgen::writer::SourceWriter;
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum DefineKey<'a> {
|
||||
Boolean(&'a str),
|
||||
Named(&'a str, &'a str),
|
||||
@@ -52,6 +54,36 @@ pub enum Cfg {
|
||||
Not(Box<Cfg>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Cfg {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Cfg::Boolean(key) => write!(f, "{}", key),
|
||||
Cfg::Named(key, value) => write!(f, "{} = {:?}", key, value),
|
||||
Cfg::Any(cfgs) => {
|
||||
write!(f, "any(")?;
|
||||
for (index, cfg) in cfgs.iter().enumerate() {
|
||||
if index > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", cfg)?;
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
Cfg::All(cfgs) => {
|
||||
write!(f, "all(")?;
|
||||
for (index, cfg) in cfgs.iter().enumerate() {
|
||||
if index > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", cfg)?;
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
Cfg::Not(cfg) => write!(f, "not({})", cfg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cfg {
|
||||
pub fn join(cfgs: &[Cfg]) -> Option<Cfg> {
|
||||
if cfgs.len() == 0 {
|
||||
@@ -166,139 +198,161 @@ impl Cfg {
|
||||
Some(configs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn has_defines(&self, config: &Config) -> bool {
|
||||
pub trait ToCondition: Sized {
|
||||
type Output;
|
||||
|
||||
fn to_condition(self, config: &Config) -> Option<Self::Output>;
|
||||
}
|
||||
|
||||
impl<'a> ToCondition for &'a Option<Cfg> {
|
||||
type Output = Condition;
|
||||
|
||||
fn to_condition(self, config: &Config) -> Option<Self::Output> {
|
||||
self.clone().and_then(|cfg| cfg.to_condition(config))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCondition for Option<Cfg> {
|
||||
type Output = Condition;
|
||||
|
||||
fn to_condition(self, config: &Config) -> Option<Self::Output> {
|
||||
self.and_then(|cfg| cfg.to_condition(config))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToCondition for &'a Cfg {
|
||||
type Output = Condition;
|
||||
|
||||
fn to_condition(self, config: &Config) -> Option<Self::Output> {
|
||||
self.clone().to_condition(config)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCondition for Cfg {
|
||||
type Output = Condition;
|
||||
|
||||
fn to_condition(self, config: &Config) -> Option<Self::Output> {
|
||||
match self {
|
||||
&Cfg::Boolean(ref cfg_name) => {
|
||||
for (key, ..) in &config.defines {
|
||||
let key = DefineKey::load(key);
|
||||
|
||||
match key {
|
||||
DefineKey::Boolean(key_name) => if cfg_name == key_name {
|
||||
return true;
|
||||
},
|
||||
DefineKey::Named(..) => {}
|
||||
}
|
||||
Cfg::Boolean(cfg_name) => {
|
||||
let define = config
|
||||
.defines
|
||||
.iter()
|
||||
.find(|(key, ..)| DefineKey::Boolean(&cfg_name) == DefineKey::load(key));
|
||||
if let Some((_, define)) = define {
|
||||
Some(Condition::Define(define.to_owned()))
|
||||
} else {
|
||||
warn!(
|
||||
"Missing `[defines]` entry for `{}` in cbindgen config.",
|
||||
Cfg::Boolean(cfg_name)
|
||||
);
|
||||
None
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
&Cfg::Named(ref cfg_name, ref cfg_value) => {
|
||||
for (key, ..) in &config.defines {
|
||||
let key = DefineKey::load(key);
|
||||
|
||||
match key {
|
||||
DefineKey::Boolean(..) => {}
|
||||
DefineKey::Named(key_name, key_value) => {
|
||||
if cfg_name == key_name && cfg_value == key_value {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Cfg::Named(cfg_name, cfg_value) => {
|
||||
let define = config.defines.iter().find(|(key, ..)| {
|
||||
DefineKey::Named(&cfg_name, &cfg_value) == DefineKey::load(key)
|
||||
});
|
||||
if let Some((_, define)) = define {
|
||||
Some(Condition::Define(define.to_owned()))
|
||||
} else {
|
||||
warn!(
|
||||
"Missing `[defines]` entry for `{}` in cbindgen config.",
|
||||
Cfg::Named(cfg_name, cfg_value)
|
||||
);
|
||||
None
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
&Cfg::Any(ref cfgs) => cfgs.iter().all(|x| x.has_defines(config)),
|
||||
&Cfg::All(ref cfgs) => cfgs.iter().all(|x| x.has_defines(config)),
|
||||
&Cfg::Not(ref cfg) => cfg.has_defines(config),
|
||||
Cfg::Any(children) => {
|
||||
let conditions: Vec<_> = children
|
||||
.into_iter()
|
||||
.filter_map(|x| x.to_condition(config))
|
||||
.collect();
|
||||
match conditions.len() {
|
||||
0 => None,
|
||||
1 => conditions.into_iter().next(),
|
||||
_ => Some(Condition::Any(conditions)),
|
||||
}
|
||||
}
|
||||
Cfg::All(children) => {
|
||||
let cfgs: Vec<_> = children
|
||||
.into_iter()
|
||||
.filter_map(|x| x.to_condition(config))
|
||||
.collect();
|
||||
match cfgs.len() {
|
||||
0 => None,
|
||||
1 => cfgs.into_iter().next(),
|
||||
_ => Some(Condition::All(cfgs)),
|
||||
}
|
||||
}
|
||||
Cfg::Not(child) => child
|
||||
.to_condition(config)
|
||||
.map(|cfg| Condition::Not(Box::new(cfg))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_condition<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Condition {
|
||||
Define(String),
|
||||
Any(Vec<Condition>),
|
||||
All(Vec<Condition>),
|
||||
Not(Box<Condition>),
|
||||
}
|
||||
|
||||
impl Condition {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
match self {
|
||||
&Cfg::Boolean(ref cfg_name) => {
|
||||
let mut define: &str = cfg_name;
|
||||
|
||||
for (key, define_value) in &config.defines {
|
||||
let key = DefineKey::load(key);
|
||||
|
||||
match key {
|
||||
DefineKey::Boolean(key_name) => if cfg_name == key_name {
|
||||
define = define_value;
|
||||
},
|
||||
DefineKey::Named(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
&Condition::Define(ref define) => {
|
||||
out.write("defined(");
|
||||
write!(out, "{}", define);
|
||||
out.write(")");
|
||||
}
|
||||
&Cfg::Named(ref cfg_name, ref cfg_value) => {
|
||||
let mut define: &str = cfg_name;
|
||||
|
||||
for (key, define_value) in &config.defines {
|
||||
let key = DefineKey::load(key);
|
||||
|
||||
match key {
|
||||
DefineKey::Boolean(..) => {}
|
||||
DefineKey::Named(key_name, key_value) => {
|
||||
if cfg_name == key_name && cfg_value == key_value {
|
||||
define = define_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.write("defined(");
|
||||
write!(out, "{}", define);
|
||||
out.write(")");
|
||||
}
|
||||
&Cfg::Any(ref cfgs) => {
|
||||
&Condition::Any(ref conditions) => {
|
||||
out.write("(");
|
||||
for (i, cfg) in cfgs.iter().enumerate() {
|
||||
for (i, condition) in conditions.iter().enumerate() {
|
||||
if i != 0 {
|
||||
out.write(" || ");
|
||||
}
|
||||
cfg.write_condition(config, out);
|
||||
condition.write(config, out);
|
||||
}
|
||||
out.write(")");
|
||||
}
|
||||
&Cfg::All(ref cfgs) => {
|
||||
&Condition::All(ref conditions) => {
|
||||
out.write("(");
|
||||
for (i, cfg) in cfgs.iter().enumerate() {
|
||||
for (i, condition) in conditions.iter().enumerate() {
|
||||
if i != 0 {
|
||||
out.write(" && ");
|
||||
}
|
||||
cfg.write_condition(config, out);
|
||||
condition.write(config, out);
|
||||
}
|
||||
out.write(")");
|
||||
}
|
||||
&Cfg::Not(ref cfg) => {
|
||||
&Condition::Not(ref condition) => {
|
||||
out.write("!");
|
||||
cfg.write_condition(config, out);
|
||||
condition.write(config, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CfgWrite {
|
||||
pub trait ConditionWrite {
|
||||
fn write_before<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>);
|
||||
|
||||
fn write_after<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>);
|
||||
}
|
||||
|
||||
impl CfgWrite for Option<Cfg> {
|
||||
impl ConditionWrite for Option<Condition> {
|
||||
fn write_before<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
if let &Some(ref cfg) = self {
|
||||
if !cfg.has_defines(config) {
|
||||
return;
|
||||
}
|
||||
|
||||
out.write("#if ");
|
||||
cfg.write_condition(config, out);
|
||||
cfg.write(config, out);
|
||||
out.new_line();
|
||||
}
|
||||
}
|
||||
|
||||
fn write_after<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
if let &Some(ref cfg) = self {
|
||||
// TODO
|
||||
if !cfg.has_defines(config) {
|
||||
return;
|
||||
}
|
||||
|
||||
fn write_after<F: Write>(&self, _config: &Config, out: &mut SourceWriter<F>) {
|
||||
if self.is_some() {
|
||||
out.new_line();
|
||||
out.write("#endif");
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ use syn;
|
||||
|
||||
use bindgen::config::{Config, Language};
|
||||
use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, Item, ItemContainer, Type};
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, Item, ItemContainer, ToCondition, Type,
|
||||
};
|
||||
use bindgen::writer::{Source, SourceWriter};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -137,7 +139,8 @@ impl Item for Constant {
|
||||
|
||||
impl Source for Constant {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
self.cfg.write_before(config, out);
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
condition.write_before(config, out);
|
||||
if config.constant.allow_static_const && config.language == Language::Cxx {
|
||||
if let Type::ConstPtr(..) = self.ty {
|
||||
out.write("static ");
|
||||
@@ -149,6 +152,6 @@ impl Source for Constant {
|
||||
} else {
|
||||
write!(out, "#define {} {}", self.name, self.value.0)
|
||||
}
|
||||
self.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ use bindgen::config::{Config, Language};
|
||||
use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, GenericPath, Item, ItemContainer,
|
||||
Repr, ReprStyle, ReprType, Struct, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, GenericPath, Item,
|
||||
ItemContainer, Repr, ReprStyle, ReprType, Struct, ToCondition, Type,
|
||||
};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::rename::{IdentifierType, RenameRule};
|
||||
@@ -317,7 +317,9 @@ impl Source for Enum {
|
||||
ReprType::I8 => "int8_t",
|
||||
});
|
||||
|
||||
self.cfg.write_before(config, out);
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
|
||||
condition.write_before(config, out);
|
||||
|
||||
self.documentation.write(config, out);
|
||||
|
||||
@@ -543,6 +545,6 @@ impl Source for Enum {
|
||||
}
|
||||
}
|
||||
|
||||
self.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ use bindgen::cdecl;
|
||||
use bindgen::config::{Config, Language, Layout};
|
||||
use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, PrimitiveType, Type};
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, PrimitiveType, ToCondition, Type,
|
||||
};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::monomorph::Monomorphs;
|
||||
use bindgen::rename::{IdentifierType, RenameRule};
|
||||
@@ -126,7 +128,8 @@ impl Source for Function {
|
||||
let prefix = config.function.prefix(&func.annotations);
|
||||
let postfix = config.function.postfix(&func.annotations);
|
||||
|
||||
func.cfg.write_before(config, out);
|
||||
let condition = (&func.cfg).to_condition(config);
|
||||
condition.write_before(config, out);
|
||||
|
||||
func.documentation.write(config, out);
|
||||
|
||||
@@ -147,7 +150,7 @@ impl Source for Function {
|
||||
}
|
||||
out.write(";");
|
||||
|
||||
func.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
|
||||
fn write_2<W: Write>(func: &Function, config: &Config, out: &mut SourceWriter<W>) {
|
||||
@@ -155,7 +158,9 @@ impl Source for Function {
|
||||
let prefix = config.function.prefix(&func.annotations);
|
||||
let postfix = config.function.postfix(&func.annotations);
|
||||
|
||||
func.cfg.write_before(config, out);
|
||||
let condition = (&func.cfg).to_condition(config);
|
||||
|
||||
condition.write_before(config, out);
|
||||
|
||||
func.documentation.write(config, out);
|
||||
|
||||
@@ -176,7 +181,7 @@ impl Source for Function {
|
||||
}
|
||||
out.write(";");
|
||||
|
||||
func.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
};
|
||||
|
||||
let option_1 = out.measure(|out| write_1(self, config, out));
|
||||
|
||||
@@ -10,7 +10,8 @@ use bindgen::config::{Config, Language};
|
||||
use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer, Path, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Path,
|
||||
ToCondition, Type,
|
||||
};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::mangle;
|
||||
@@ -107,7 +108,8 @@ impl Item for OpaqueItem {
|
||||
|
||||
impl Source for OpaqueItem {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
self.cfg.write_before(config, out);
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
condition.write_before(config, out);
|
||||
|
||||
self.documentation.write(config, out);
|
||||
|
||||
@@ -119,6 +121,6 @@ impl Source for OpaqueItem {
|
||||
write!(out, "struct {};", self.name);
|
||||
}
|
||||
|
||||
self.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ use bindgen::config::{Config, Language};
|
||||
use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer, Repr, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Repr,
|
||||
ToCondition, Type,
|
||||
};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::mangle;
|
||||
@@ -234,7 +235,8 @@ impl Item for Struct {
|
||||
|
||||
impl Source for Struct {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
self.cfg.write_before(config, out);
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
condition.write_before(config, out);
|
||||
|
||||
self.documentation.write(config, out);
|
||||
|
||||
@@ -396,7 +398,7 @@ impl Source for Struct {
|
||||
out.close_brace(true);
|
||||
}
|
||||
|
||||
self.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ use bindgen::config::{Config, Language};
|
||||
use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer, Path, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Path,
|
||||
ToCondition, Type,
|
||||
};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::mangle;
|
||||
@@ -168,7 +169,8 @@ impl Item for Typedef {
|
||||
|
||||
impl Source for Typedef {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
self.cfg.write_before(config, out);
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
condition.write_before(config, out);
|
||||
|
||||
self.documentation.write(config, out);
|
||||
|
||||
@@ -183,6 +185,6 @@ impl Source for Typedef {
|
||||
}
|
||||
out.write(";");
|
||||
|
||||
self.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ use bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::SynFieldHelpers;
|
||||
use bindgen::ir::{
|
||||
AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer, Repr, Type,
|
||||
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Repr,
|
||||
ToCondition, Type,
|
||||
};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::mangle;
|
||||
@@ -220,7 +221,8 @@ impl Item for Union {
|
||||
|
||||
impl Source for Union {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
self.cfg.write_before(config, out);
|
||||
let condition = (&self.cfg).to_condition(config);
|
||||
condition.write_before(config, out);
|
||||
|
||||
self.documentation.write(config, out);
|
||||
|
||||
@@ -265,6 +267,6 @@ impl Source for Union {
|
||||
out.close_brace(true);
|
||||
}
|
||||
|
||||
self.cfg.write_after(config, out);
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(BAR)
|
||||
#define BAR 2
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
#define FOO 1
|
||||
#endif
|
||||
|
||||
#if defined(BAR)
|
||||
typedef struct Bar {
|
||||
|
||||
} Bar;
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
typedef struct Foo {
|
||||
|
||||
} Foo;
|
||||
#endif
|
||||
|
||||
#if defined(BAR)
|
||||
void bar(const Bar *bar);
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
void foo(const Foo *foo);
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(BAR)
|
||||
#define BAR 2
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
#define FOO 1
|
||||
#endif
|
||||
|
||||
#if defined(BAR)
|
||||
typedef struct {
|
||||
|
||||
} Bar;
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
typedef struct {
|
||||
|
||||
} Foo;
|
||||
#endif
|
||||
|
||||
#if defined(BAR)
|
||||
void bar(const Bar *bar);
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
void foo(const Foo *foo);
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
#if defined(BAR)
|
||||
static const int32_t BAR = 2;
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
static const int32_t FOO = 1;
|
||||
#endif
|
||||
|
||||
#if defined(BAR)
|
||||
struct Bar {
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
struct Foo {
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
#if defined(BAR)
|
||||
void bar(const Bar *bar);
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
void foo(const Foo *foo);
|
||||
#endif
|
||||
|
||||
} // extern "C"
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(BAR)
|
||||
#define BAR 2
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
#define FOO 1
|
||||
#endif
|
||||
|
||||
#if defined(BAR)
|
||||
struct Bar {
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
struct Foo {
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(BAR)
|
||||
void bar(const struct Bar *bar);
|
||||
#endif
|
||||
|
||||
#if defined(FOO)
|
||||
void foo(const struct Foo *foo);
|
||||
#endif
|
||||
Generated
+4
@@ -0,0 +1,4 @@
|
||||
[[package]]
|
||||
name = "mod_attr"
|
||||
version = "0.1.0"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "mod_attr"
|
||||
version = "0.1.0"
|
||||
authors = ["cbindgen"]
|
||||
|
||||
[lib]
|
||||
name = "mod_attr"
|
||||
crate-type = ["lib", "dylib"]
|
||||
|
||||
[features]
|
||||
foobar = []
|
||||
@@ -0,0 +1,4 @@
|
||||
[defines]
|
||||
"foo" = "FOO"
|
||||
"bar" = "BAR"
|
||||
# "feature = foobar" = "FOOBAR"
|
||||
@@ -0,0 +1,24 @@
|
||||
#[cfg(foo)]
|
||||
pub const FOO: i32 = 1;
|
||||
|
||||
#[cfg(foo)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn foo(foo: &Foo) {}
|
||||
|
||||
#[cfg(foo)]
|
||||
#[repr(C)]
|
||||
pub struct Foo {}
|
||||
|
||||
#[cfg(feature = "foobar")]
|
||||
pub mod foo {
|
||||
#[cfg(bar)]
|
||||
pub const BAR: i32 = 2;
|
||||
|
||||
#[cfg(bar)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn bar(bar: &Bar) {}
|
||||
|
||||
#[cfg(bar)]
|
||||
#[repr(C)]
|
||||
pub struct Bar {}
|
||||
}
|
||||
Reference in New Issue
Block a user