Make sentinel variant respect regular config

Like enum.prefix_with_name, or documentation style.

Fixes https://github.com/eqrion/cbindgen/issues/458
This commit is contained in:
Emilio Cobos Álvarez
2020-01-24 06:34:00 +01:00
parent 12b158c4fc
commit e0d4bc17a5
12 changed files with 515 additions and 9 deletions
+6
View File
@@ -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(),
+14 -6
View File
@@ -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());
@@ -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 {
@@ -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);
+9 -3
View File
@@ -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);
@@ -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).",
@@ -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);
+55
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+52
View File
@@ -0,0 +1,52 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
enum class A : uint8_t {
A_A1,
A_A2,
A_A3,
/// Must be last for serialization purposes
A_Sentinel,
};
enum class B : uint8_t {
B_B1,
B_B2,
B_B3,
/// Must be last for serialization purposes
B_Sentinel,
};
union C {
enum class Tag : uint8_t {
C_C1,
C_C2,
C_C3,
/// Must be last for serialization purposes
C_Sentinel,
};
struct C_C1_Body {
Tag tag;
uint32_t a;
};
struct C_C2_Body {
Tag tag;
uint32_t b;
};
struct {
Tag tag;
};
C_C1_Body c1;
C_C2_Body c2;
};
extern "C" {
void root(A a, B b, C c);
} // extern "C"
+55
View File
@@ -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;
struct C_C1_Body {
C_Tag tag;
uint32_t a;
};
struct C_C2_Body {
C_Tag tag;
uint32_t b;
};
union C {
enum C_Tag tag;
struct C_C1_Body c1;
struct C_C2_Body c2;
};
void root(A a, B b, union C c);
+81
View File
@@ -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
struct C_C1_Body {
C_Tag tag;
uint32_t a;
};
struct C_C2_Body {
C_Tag tag;
uint32_t b;
};
union C {
enum C_Tag tag;
struct C_C1_Body c1;
struct C_C2_Body c2;
};
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(A a, B b, union C c);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+23
View File
@@ -0,0 +1,23 @@
#[repr(u8)]
pub enum A {
A1,
A2,
A3,
}
#[repr(u8)]
pub enum B {
B1,
B2,
B3,
}
#[repr(u8)]
pub enum C {
C1 { a: u32 },
C2 { b: u32 },
C3,
}
#[no_mangle]
pub extern "C" fn root(a: A, b: B, c: C) {}
+3
View File
@@ -0,0 +1,3 @@
[enum]
add_sentinel = true
prefix_with_name = true