Skip to content

Commit

Permalink
C with macro
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowone committed Aug 10, 2024
1 parent d937f8b commit dd3faf9
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 38 deletions.
52 changes: 31 additions & 21 deletions src/bindgen/ir/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,33 +328,43 @@ pub trait ConditionWrite {
fn write_after<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>);
}

impl ConditionWrite for Condition {
fn write_before<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
if config.language == Language::Cython {
out.write("IF ");
self.write(config, out);
out.open_brace();
} else {
out.push_set_spaces(0);
out.write("#if ");
self.write(config, out);
out.pop_set_spaces();
out.new_line();
}
}

fn write_after<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
if config.language == Language::Cython {
out.close_brace(false);
} else {
out.new_line();
out.push_set_spaces(0);
out.write("#endif");
out.pop_set_spaces();
}
}
}

impl ConditionWrite for Option<Condition> {
fn write_before<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
if let Some(ref cfg) = *self {
if config.language == Language::Cython {
out.write("IF ");
cfg.write(config, out);
out.open_brace();
} else {
out.push_set_spaces(0);
out.write("#if ");
cfg.write(config, out);
out.pop_set_spaces();
out.new_line();
}
if let Some(cfg) = self {
cfg.write_before(config, out)
}
}

fn write_after<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
if self.is_some() {
if config.language == Language::Cython {
out.close_brace(false);
} else {
out.new_line();
out.push_set_spaces(0);
out.write("#endif");
out.pop_set_spaces();
}
if let Some(cfg) = self {
cfg.write_after(config, out);
}
}
}
51 changes: 37 additions & 14 deletions src/bindgen/language_backend/clike.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,31 +923,54 @@ impl LanguageBackend for CLikeLanguageBackend<'_> {
for (i, ordered_key) in ordered_fields.iter().enumerate() {
if let Some(lit) = fields.get(ordered_key) {
let condition = lit.cfg.to_condition(self.config);
if condition.is_some() {
out.new_line();
}

condition.write_before(self.config, out);
if self.config.language == Language::Cxx {
if condition.is_some() {
out.new_line();
}
condition.write_before(self.config, out);
// TODO: Some C++ versions (c++20?) now support designated
// initializers, consider generating them.
write!(out, "/* .{} = */ ", ordered_key);
self.write_literal(out, &lit.value);
if i + 1 != ordered_fields.len() {
write!(out, ", ");
}
condition.write_after(self.config, out);
if condition.is_some() {
out.new_line();
}
} else {
if i > 0 {
write!(out, ", ");
}
write!(out, ".{} = ", ordered_key);
if condition.is_some() {
write!(out, "__{export_name}_{ordered_key}(");
self.write_literal(out, &lit.value);
write!(out, ")")
} else {
self.write_literal(out, &lit.value);
}
}
self.write_literal(out, &lit.value);

if i + 1 != ordered_fields.len() {
write!(out, ", ");
}
}
}
write!(out, " }}");

condition.write_after(self.config, out);
if condition.is_some() {
out.new_line();
if self.config.language == Language::C {
for ordered_key in ordered_fields.iter() {
if let Some(lit) = fields.get(ordered_key) {
if let Some(condition) = lit.cfg.to_condition(self.config) {
out.new_line();
condition.write_before(self.config, out);
let define = format!("#define __{export_name}_{ordered_key}(v)");
write!(out, "{define} (v)");
write!(out, "\n#else\n");
write!(out, "{define}");
condition.write_after(self.config, out);
}
}
}
}
write!(out, " }}");
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ typedef struct {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){ .field = __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ .field = __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif

typedef struct {
int32_t x;
Expand Down
13 changes: 10 additions & 3 deletions tests/expectations/cfg.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,18 @@ typedef struct {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){
#define ConditionalField_ZERO (ConditionalField){ .field = __ConditionalField_field(0) }
#if defined(X11)
.field = 0
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ .field = __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif
}

typedef struct {
int32_t x;
Expand Down
10 changes: 10 additions & 0 deletions tests/expectations/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,16 @@ struct ConditionalField {
#endif
;
};
constexpr static const ConditionalField ConditionalField_ZERO = ConditionalField{
#if defined(X11)
/* .field = */ 0
#endif
};
constexpr static const ConditionalField ConditionalField_ONE = ConditionalField{
#if defined(X11)
/* .field = */ 1
#endif
};

struct Normal {
int32_t x;
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/cfg.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ cdef extern from *:

ctypedef struct ConditionalField:
int32_t field;
const ConditionalField ConditionalField_ZERO # = <ConditionalField>{ 0 }
const ConditionalField ConditionalField_ONE # = <ConditionalField>{ 1 }

ctypedef struct Normal:
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_both.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ typedef struct ConditionalField {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){ .field = __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ .field = __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif

typedef struct Normal {
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_both.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ typedef struct ConditionalField {
#endif
;
} ConditionalField;
#define ConditionalField_ZERO (ConditionalField){ .field = __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ .field = __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif

typedef struct Normal {
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ struct ConditionalField {
#endif
;
};
#define ConditionalField_ZERO (ConditionalField){ .field = __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ .field = __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif

struct Normal {
int32_t x;
Expand Down
12 changes: 12 additions & 0 deletions tests/expectations/cfg_tag.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ struct ConditionalField {
#endif
;
};
#define ConditionalField_ZERO (ConditionalField){ .field = __ConditionalField_field(0) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif
#define ConditionalField_ONE (ConditionalField){ .field = __ConditionalField_field(1) }
#if defined(X11)
#define __ConditionalField_field(v) (v)
#else
#define __ConditionalField_field(v)
#endif

struct Normal {
int32_t x;
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/cfg_tag.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ cdef extern from *:

cdef struct ConditionalField:
int32_t field;
const ConditionalField ConditionalField_ZERO # = <ConditionalField>{ 0 }
const ConditionalField ConditionalField_ONE # = <ConditionalField>{ 1 }

cdef struct Normal:
int32_t x;
Expand Down
4 changes: 4 additions & 0 deletions tests/rust/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ impl ConditionalField {
#[cfg(x11)]
field: 0,
};
pub const ONE: Self = Self {
#[cfg(x11)]
field: 1,
};
}

#[cfg(all(unix, x11))]
Expand Down

0 comments on commit dd3faf9

Please sign in to comment.