Skip to content

Commit

Permalink
Make sentinel variant respect regular config
Browse files Browse the repository at this point in the history
Like enum.prefix_with_name, or documentation style.

Fixes #458
  • Loading branch information
emilio committed Jan 24, 2020
1 parent 12b158c commit e0d4bc1
Show file tree
Hide file tree
Showing 12 changed files with 515 additions and 9 deletions.
6 changes: 6 additions & 0 deletions src/bindgen/ir/documentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ impl Documentation {
Documentation { doc_comment: doc }
}

pub fn simple(line: &str) -> Self {
Documentation {
doc_comment: vec![line.to_owned()],
}
}

pub fn none() -> Self {
Documentation {
doc_comment: Vec::new(),
Expand Down
20 changes: 14 additions & 6 deletions src/bindgen/ir/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,11 @@ impl Enum {
}
}

pub fn load(item: &syn::ItemEnum, mod_cfg: Option<&Cfg>) -> Result<Enum, String> {
pub fn load(
item: &syn::ItemEnum,
mod_cfg: Option<&Cfg>,
config: &Config,
) -> Result<Enum, String> {
let repr = Repr::load(&item.attrs)?;
if repr.style == ReprStyle::Rust && repr.ty.is_none() {
return Err("Enum is not marked with a valid #[repr(prim)] or #[repr(C)].".to_owned());
Expand Down Expand Up @@ -289,6 +293,15 @@ impl Enum {
}
}

if config.enumeration.add_sentinel(&annotations) {
variants.push(EnumVariant::new(
"Sentinel".to_owned(),
None,
None,
Documentation::simple(" Must be last for serialization purposes"),
));
}

let tag = if is_tagged {
Some("Tag".to_string())
} else {
Expand Down Expand Up @@ -596,11 +609,6 @@ impl Source for Enum {
}
variant.write(config, out);
}
if config.enumeration.add_sentinel(&self.annotations) {
out.new_line();
out.new_line();
out.write("Sentinel /* this must be last for serialization purposes. */");
}

if config.language == Language::C && size.is_none() && config.style.generate_typedef() {
out.close_brace(false);
Expand Down
12 changes: 9 additions & 3 deletions src/bindgen/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ impl Parse {
self.load_syn_union(config, crate_name, mod_cfg, item);
}
syn::Item::Enum(ref item) => {
self.load_syn_enum(crate_name, mod_cfg, item);
self.load_syn_enum(config, crate_name, mod_cfg, item);
}
syn::Item::Type(ref item) => {
self.load_syn_ty(crate_name, mod_cfg, item);
Expand Down Expand Up @@ -860,7 +860,13 @@ impl Parse {
}

/// Loads a `enum` declaration
fn load_syn_enum(&mut self, crate_name: &str, mod_cfg: Option<&Cfg>, item: &syn::ItemEnum) {
fn load_syn_enum(
&mut self,
config: &Config,
crate_name: &str,
mod_cfg: Option<&Cfg>,
item: &syn::ItemEnum,
) {
if item.generics.lifetimes().count() > 0 {
info!(
"Skip {}::{} - (has generics or lifetimes or where bounds).",
Expand All @@ -869,7 +875,7 @@ impl Parse {
return;
}

match Enum::load(item, mod_cfg) {
match Enum::load(item, mod_cfg, config) {
Ok(en) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.enums.try_insert(en);
Expand Down
55 changes: 55 additions & 0 deletions tests/expectations/both/sentinel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

enum A {
A_A1,
A_A2,
A_A3,
/**
* Must be last for serialization purposes
*/
A_Sentinel,
};
typedef uint8_t A;

enum B {
B_B1,
B_B2,
B_B3,
/**
* Must be last for serialization purposes
*/
B_Sentinel,
};
typedef uint8_t B;

enum C_Tag {
C_C1,
C_C2,
C_C3,
/**
* Must be last for serialization purposes
*/
C_Sentinel,
};
typedef uint8_t C_Tag;

typedef struct C_C1_Body {
C_Tag tag;
uint32_t a;
} C_C1_Body;

typedef struct C_C2_Body {
C_Tag tag;
uint32_t b;
} C_C2_Body;

typedef union C {
C_Tag tag;
C_C1_Body c1;
C_C2_Body c2;
} C;

void root(A a, B b, C c);
81 changes: 81 additions & 0 deletions tests/expectations/both/sentinel.compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

enum A
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
A_A1,
A_A2,
A_A3,
/**
* Must be last for serialization purposes
*/
A_Sentinel,
};
#ifndef __cplusplus
typedef uint8_t A;
#endif // __cplusplus

enum B
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
B_B1,
B_B2,
B_B3,
/**
* Must be last for serialization purposes
*/
B_Sentinel,
};
#ifndef __cplusplus
typedef uint8_t B;
#endif // __cplusplus

enum C_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
C_C1,
C_C2,
C_C3,
/**
* Must be last for serialization purposes
*/
C_Sentinel,
};
#ifndef __cplusplus
typedef uint8_t C_Tag;
#endif // __cplusplus

typedef struct C_C1_Body {
C_Tag tag;
uint32_t a;
} C_C1_Body;

typedef struct C_C2_Body {
C_Tag tag;
uint32_t b;
} C_C2_Body;

typedef union C {
C_Tag tag;
C_C1_Body c1;
C_C2_Body c2;
} C;

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

void root(A a, B b, C c);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
55 changes: 55 additions & 0 deletions tests/expectations/sentinel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

enum A {
A_A1,
A_A2,
A_A3,
/**
* Must be last for serialization purposes
*/
A_Sentinel,
};
typedef uint8_t A;

enum B {
B_B1,
B_B2,
B_B3,
/**
* Must be last for serialization purposes
*/
B_Sentinel,
};
typedef uint8_t B;

enum C_Tag {
C_C1,
C_C2,
C_C3,
/**
* Must be last for serialization purposes
*/
C_Sentinel,
};
typedef uint8_t C_Tag;

typedef struct {
C_Tag tag;
uint32_t a;
} C_C1_Body;

typedef struct {
C_Tag tag;
uint32_t b;
} C_C2_Body;

typedef union {
C_Tag tag;
C_C1_Body c1;
C_C2_Body c2;
} C;

void root(A a, B b, C c);
81 changes: 81 additions & 0 deletions tests/expectations/sentinel.compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

enum A
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
A_A1,
A_A2,
A_A3,
/**
* Must be last for serialization purposes
*/
A_Sentinel,
};
#ifndef __cplusplus
typedef uint8_t A;
#endif // __cplusplus

enum B
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
B_B1,
B_B2,
B_B3,
/**
* Must be last for serialization purposes
*/
B_Sentinel,
};
#ifndef __cplusplus
typedef uint8_t B;
#endif // __cplusplus

enum C_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
C_C1,
C_C2,
C_C3,
/**
* Must be last for serialization purposes
*/
C_Sentinel,
};
#ifndef __cplusplus
typedef uint8_t C_Tag;
#endif // __cplusplus

typedef struct {
C_Tag tag;
uint32_t a;
} C_C1_Body;

typedef struct {
C_Tag tag;
uint32_t b;
} C_C2_Body;

typedef union {
C_Tag tag;
C_C1_Body c1;
C_C2_Body c2;
} C;

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

void root(A a, B b, C c);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
Loading

0 comments on commit e0d4bc1

Please sign in to comment.